GCC Code Coverage Report


Directory: ./
File: obj_opt/V3Const__gen.cpp
Date: 2025-04-17 19:39:58
Exec Total Coverage
Lines: 1285 2015 63.8%
Functions: 255 410 62.2%
Branches: 1378 4288 32.1%

Line Branch Exec Source
1 // Generated by astgen // -*- mode: C++; c-file-style: "cc-mode" -*-
2 #line 1 "../V3Const.cpp"
3 // -*- mode: C++; c-file-style: "cc-mode" -*-
4 //*************************************************************************
5 // DESCRIPTION: Verilator: Constant folding
6 //
7 // Code available from: https://verilator.org
8 //
9 //*************************************************************************
10 //
11 // Copyright 2003-2025 by Wilson Snyder. This program is free software; you
12 // can redistribute it and/or modify it under the terms of either the GNU
13 // Lesser General Public License Version 3 or the Perl Artistic License
14 // Version 2.0.
15 // SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
16 //
17 //*************************************************************************
18 // CONST TRANSFORMATIONS:
19 // Call on one node for PARAM values, or netlist for overall constant folding:
20 // Bottom up traversal:
21 // Attempt to convert operands to constants
22 // If operands are constant, replace this node with constant.
23 //*************************************************************************
24
25 #include "V3PchAstNoMT.h" // VL_MT_DISABLED_CODE_UNIT
26
27 #include "config_build.h"
28 #include "verilatedos.h"
29
30 #include "V3Const.h"
31
32 #include "V3Ast.h"
33 #include "V3Global.h"
34 #include "V3Simulate.h"
35 #include "V3Stats.h"
36 #include "V3String.h"
37 #include "V3UniqueNames.h"
38 #include "V3Width.h"
39
40 #include <algorithm>
41 #include <memory>
42 #include <type_traits>
43
44 VL_DEFINE_DEBUG_FUNCTIONS;
45
46 #define TREE_SKIP_VISIT(...)
47 #define TREEOP1(...)
48 #define TREEOPA(...)
49 #define TREEOP(...)
50 #define TREEOPS(...)
51 #define TREEOPC(...)
52 #define TREEOPV(...)
53
54 //######################################################################
55 // Utilities
56
57 static bool isConst(const AstNode* nodep, uint64_t v) {
58 const AstConst* const constp = VN_CAST(nodep, Const);
59 return constp && constp->toUQuad() == v;
60 }
61
62 template <typename T>
63 static typename std::enable_if<std::is_integral<T>::value, bool>::type isPow2(T val) {
64 return (val & (val - 1)) == 0;
65 }
66
67 static int countTrailingZeroes(uint64_t val) {
68 UASSERT(val, "countTrailingZeroes argument must be non-zero");
69 #if defined(__GNUC__) && !defined(VL_NO_BUILTINS)
70 return __builtin_ctzll(val);
71 #else
72 int bit = 0;
73 val = ~val;
74 while (val & 1) {
75 ++bit;
76 val >>= 1;
77 }
78 return bit;
79 #endif
80 }
81
82 // This visitor can be used in the post-expanded Ast from V3Expand, where the Ast satisfies:
83 // - Constants are 64 bit at most (because words are accessed via AstWordSel)
84 // - Variables are scoped.
85 class ConstBitOpTreeVisitor final : public VNVisitorConst {
86 // NODE STATE
87 // AstVarRef::user4u -> Base index of m_varInfos that points VarInfo
88 // AstVarScope::user4u -> Same as AstVarRef::user4
89 const VNUser4InUse m_inuser4;
90
91 // TYPES
92
93 // Holds a node to be added as a term in the reduction tree, it's equivalent op count, and a
94 // bool indicating if the term is clean (0/1 value, or if the top bits might be dirty)
95 using ResultTerm = std::tuple<AstNodeExpr*, unsigned, bool>;
96
97 class LeafInfo final { // Leaf node (either AstConst or AstVarRef)
98 // MEMBERS
99 bool m_polarity = true;
100 int m_lsb = 0; // LSB of actually used bit of m_refp->varp()
101 int m_msb = 0; // MSB of actually used bit of m_refp->varp()
102 int m_wordIdx = -1; // -1 means AstWordSel is not used.
103 AstVarRef* m_refp = nullptr;
104 const AstConst* m_constp = nullptr;
105
106 public:
107 // CONSTRUCTORS
108 LeafInfo() = default;
109 LeafInfo(const LeafInfo& other) = default;
110 explicit LeafInfo(int lsb)
111 : m_lsb{lsb} {}
112
113 // METHODS
114 void setLeaf(AstVarRef* refp) {
115 UASSERT_OBJ(!m_refp && !m_constp, refp, "Must be called just once");
116 m_refp = refp;
117 m_msb = refp->varp()->widthMin() - 1;
118 }
119 void setLeaf(const AstConst* constp) {
120 UASSERT_OBJ(!m_refp && !m_constp, constp, "Must be called just once");
121 m_constp = constp;
122 m_msb = constp->widthMin() - 1;
123 }
124 void updateBitRange(const AstCCast* castp) {
125 m_msb = std::min(m_msb, m_lsb + castp->width() - 1);
126 }
127 void updateBitRange(const AstShiftR* shiftp) {
128 m_lsb += VN_AS(shiftp->rhsp(), Const)->toUInt();
129 }
130 int wordIdx() const { return m_wordIdx; }
131 void wordIdx(int i) { m_wordIdx = i; }
132 bool polarity() const { return m_polarity; }
133 void polarity(bool p) { m_polarity = p; }
134
135 AstVarRef* refp() const { return m_refp; }
136 const AstConst* constp() const { return m_constp; }
137 bool missingWordSel() const {
138 // When V3Expand is skipped, WordSel is not inserted.
139 return m_refp->isWide() && m_wordIdx == -1;
140 }
141 int lsb() const { return m_lsb; }
142
143 int msb() const { return std::min(m_msb, varWidth() - 1); }
144 int varWidth() const {
145 UASSERT(m_refp, "m_refp should be set");
146 const int width = m_refp->varp()->widthMin();
147 if (!m_refp->isWide()) {
148 UASSERT_OBJ(m_wordIdx == -1, m_refp, "Bad word index into non-wide");
149 return width;
150 } else {
151 if (missingWordSel()) return width;
152 UASSERT_OBJ(m_wordIdx >= 0, m_refp, "Bad word index into wide");
153 const int bitsInMSW = VL_BITBIT_E(width) ? VL_BITBIT_E(width) : VL_EDATASIZE;
154 return m_wordIdx == m_refp->widthWords() - 1 ? bitsInMSW : VL_EDATASIZE;
155 }
156 }
157 };
158
159 struct BitPolarityEntry final { // Found bit polarity during iterate()
160 LeafInfo m_info;
161 bool m_polarity;
162 int m_bit;
163 BitPolarityEntry(const LeafInfo& info, bool pol, int bit)
164 : m_info{info}
165 , m_polarity{pol}
166 , m_bit{bit} {}
167 BitPolarityEntry() = default;
168 };
169
170 struct FrozenNodeInfo final { // Context when a frozen node is found
171 bool m_polarity;
172 int m_lsb;
173 bool operator<(const FrozenNodeInfo& other) const {
174 if (m_lsb != other.m_lsb) return m_lsb < other.m_lsb;
175 return m_polarity < other.m_polarity;
176 }
177 };
178
179 class Restorer final { // Restore the original state unless disableRestore() is called
180 ConstBitOpTreeVisitor& m_visitor;
181 const size_t m_polaritiesSize;
182 const size_t m_frozenSize;
183 const unsigned m_ops;
184 const bool m_polarity;
185 bool m_restore;
186
187 public:
188 explicit Restorer(ConstBitOpTreeVisitor& visitor)
189 : m_visitor{visitor}
190 , m_polaritiesSize{visitor.m_bitPolarities.size()}
191 , m_frozenSize{visitor.m_frozenNodes.size()}
192 , m_ops{visitor.m_ops}
193 , m_polarity{visitor.m_polarity}
194 , m_restore{true} {}
195 ~Restorer() {
196 UASSERT(m_visitor.m_bitPolarities.size() >= m_polaritiesSize,
197 "m_bitPolarities must grow monotorilaclly");
198 UASSERT(m_visitor.m_frozenNodes.size() >= m_frozenSize,
199 "m_frozenNodes must grow monotorilaclly");
200 if (m_restore) restoreNow();
201 }
202 void disableRestore() { m_restore = false; }
203 void restoreNow() {
204 UASSERT(m_restore, "Can be called just once");
205 m_visitor.m_bitPolarities.resize(m_polaritiesSize);
206 m_visitor.m_frozenNodes.resize(m_frozenSize);
207 m_visitor.m_ops = m_ops;
208 m_visitor.m_polarity = m_polarity;
209 m_restore = false;
210 }
211 };
212 // Collect information for each Variable to transform as below
213 class VarInfo final {
214 // MEMBERS
215 int m_knownResult = -1; // -1: result is not known, 0 or 1: result of this tree
216 const ConstBitOpTreeVisitor* const
217 m_parentp; // ConstBitOpTreeVisitor holding this VarInfo
218 AstVarRef* const m_refp; // Points the variable that this VarInfo covers
219 const int m_width; // Width of term this VarInfo refers to
220 V3Number m_bitPolarity; // Coefficient of each bit
221
222 public:
223 // METHODS
224 bool hasConstResult() const { return m_knownResult >= 0 || m_bitPolarity.isAllX(); }
225 // The constant result. Only valid if hasConstResult() returned true.
226 bool getConstResult() const {
227 // Note that this condition covers m_knownResult == -1 but m_bitPolarity.isAllX(),
228 // in which case the result is 0
229 return m_knownResult == 1;
230 }
231 const AstVarRef* refp() const { return m_refp; }
232 bool sameVarAs(const AstNodeVarRef* otherp) const { return m_refp->sameNode(otherp); }
233 void setPolarity(bool compBit, int bit) {
234 // Ignore if already determined a known reduction
235 if (m_knownResult >= 0) return;
236 UASSERT_OBJ(bit < m_width, m_refp,
237 "Bit index out of range: " << bit << " width: " << m_width);
238 if (m_bitPolarity.bitIsX(bit)) { // The bit is not yet marked with either polarity
239 m_bitPolarity.setBit(bit, compBit);
240 } else { // The bit has already been marked with some polarity
241 const bool sameFlag = m_bitPolarity.bitIs1(bit) == compBit;
242 if (m_parentp->isXorTree()) {
243 UASSERT_OBJ(compBit && sameFlag, m_refp, "Only true is set in Xor tree");
244 // a ^ a ^ b == b so we can ignore a
245 m_bitPolarity.setBit(bit, 'x');
246 } else { // And, Or
247 // Can ignore this nodep as the bit is already marked with the same polarity
248 if (sameFlag) return; // a & a == a, b | b == b
249 // Otherwise result is constant (a & ~a == 0) or (a | ~a == 1)
250 m_knownResult = m_parentp->isAndTree() ? 0 : 1;
251 m_bitPolarity.setAllBitsX(); // The variable is not referred anymore
252 }
253 }
254 }
255
256 // Return reduction term for this VarInfo, together with the number of ops in the term,
257 // and a boolean indicating if the term is clean (1-bit vs multi-bit value)
258 ResultTerm getResultTerm() const {
259 UASSERT_OBJ(!hasConstResult(), m_refp, "getTerm on reduction that yields constant");
260 FileLine* const fl = m_refp->fileline();
261
262 // Get the term we are referencing (the WordSel, if wide, otherwise just the VarRef)
263 AstNodeExpr* srcp = VN_CAST(m_refp->backp(), WordSel);
264 if (!srcp) srcp = m_refp;
265 srcp = srcp->cloneTree(false);
266
267 // Signed variables might have redundant sign bits that need masking.
268 const bool hasRedundantSignBits
269 = m_refp->varp()->dtypep()->isSigned()
270 && (m_refp->isWide() ? (m_width != VL_EDATASIZE)
271 : (m_width < 8 || !isPow2(m_width)));
272
273 // Get the mask that selects the bits that are relevant in this term
274 V3Number maskNum{srcp, m_width, 0};
275 maskNum.opBitsNonX(m_bitPolarity); // 'x' -> 0, 0->1, 1->1
276 const uint64_t maskVal = maskNum.toUQuad();
277 UASSERT_OBJ(maskVal != 0, m_refp,
278 "Should have been recognized as having const 0 result");
279
280 // Parts of the return value
281 AstNodeExpr* resultp = srcp; // The tree for this term
282 unsigned ops = 0; // Number of ops in this term
283 bool clean = false; // Whether the term is clean (has value 0 or 1)
284
285 if (isPow2(maskVal)) {
286 // If we only want a single bit, shift it out instead of a masked compare. Shifts
287 // don't go through the flags register on x86 and are hence faster. This is also
288 // always fewer or same ops as mask and compare, but with shorter instructions on
289 // x86.
290
291 // Find the index of the bit we want.
292 const int bit = countTrailingZeroes(maskVal);
293 // If we want something other than the bottom bit, shift it out
294 if (bit != 0) {
295 resultp = new AstShiftR{fl, resultp,
296 new AstConst{fl, static_cast<uint32_t>(bit)}, m_width};
297 ++ops;
298 }
299 // Negate it if necessary
300 const bool negate = m_bitPolarity.bitIs0(bit);
301 if (negate) {
302 resultp = new AstNot{fl, resultp};
303 ++ops;
304 }
305 // Clean if MSB of unsigned value, and not negated
306 clean = (bit == m_width - 1) && !hasRedundantSignBits && !negate;
307 } else {
308 // We want multiple bits. Go ahead and extract them.
309
310 // Check if masking is required, and if so apply it
311 const bool needsMasking = maskVal != VL_MASK_Q(m_width) || hasRedundantSignBits;
312 if (needsMasking) {
313 resultp = new AstAnd{fl, new AstConst{fl, maskNum}, resultp};
314 ++ops;
315 }
316
317 // Create the sub-expression for this term
318 if (m_parentp->isXorTree()) {
319 if (needsMasking) {
320 // Reduce the masked term to the minimum known width,
321 // to use the smallest RedXor formula
322 const int widthMin = maskNum.widthMin();
323 resultp->dtypeChgWidth(widthMin, widthMin);
324 }
325 resultp = new AstRedXor{fl, resultp};
326 ++ops;
327 clean = false;
328 // VL_REDXOR_* returns IData, set width accordingly to avoid unnecessary casts
329 resultp->dtypeChgWidth(VL_IDATASIZE, 1);
330 } else if (m_parentp->isAndTree()) {
331 V3Number compNum{srcp, m_width, 0};
332 compNum.opBitsOne(m_bitPolarity); // 'x'->0, 0->0, 1->1
333 resultp = new AstEq{fl, new AstConst{fl, compNum}, resultp};
334 ++ops;
335 clean = true;
336 } else { // Or
337 V3Number compNum{srcp, m_width, 0};
338 compNum.opBitsOne(m_bitPolarity); // 'x'->0, 0->0, 1->1
339 compNum.opXor(V3Number{compNum}, maskNum);
340 resultp = new AstNeq{fl, new AstConst{fl, compNum}, resultp};
341 ++ops;
342 clean = true;
343 }
344 }
345
346 return ResultTerm{resultp, ops, clean};
347 }
348
349 // CONSTRUCTORS
350 VarInfo(ConstBitOpTreeVisitor* parent, AstVarRef* refp, int width)
351 : m_parentp{parent}
352 , m_refp{refp}
353 , m_width{width}
354 , m_bitPolarity{refp, m_width} {
355 m_bitPolarity.setAllBitsX();
356 }
357 };
358
359 // MEMBERS
360 bool m_failed = false;
361 bool m_polarity = true; // Flip when AstNot comes
362 unsigned m_ops; // Number of operations such as And, Or, Xor, Sel...
363 int m_lsb = 0; // Current LSB
364 LeafInfo* m_leafp = nullptr; // AstConst or AstVarRef that currently looking for
365 const AstNodeExpr* const m_rootp; // Root of this AST subtree
366
367 std::vector<std::pair<AstNodeExpr*, FrozenNodeInfo>>
368 m_frozenNodes; // Nodes that cannot be optimized
369 std::vector<BitPolarityEntry> m_bitPolarities; // Polarity of bits found during iterate()
370 std::vector<std::unique_ptr<VarInfo>> m_varInfos; // VarInfo for each variable, [0] is nullptr
371
372 // METHODS
373
374 bool isAndTree() const { return VN_IS(m_rootp, And); }
375 bool isOrTree() const { return VN_IS(m_rootp, Or); }
376 bool isXorTree() const { return VN_IS(m_rootp, Xor) || VN_IS(m_rootp, RedXor); }
377
378 #define CONST_BITOP_RETURN_IF(cond, nodep) \
379 if (setFailed(cond, #cond, nodep, __LINE__)) return
380
381 #define CONST_BITOP_SET_FAILED(reason, nodep) setFailed(true, reason, nodep, __LINE__)
382
383 bool setFailed(bool fail, const char* reason, AstNode* nodep, int line) {
384 if (fail && !m_failed) {
385 UINFO(9, "cannot optimize " << m_rootp << " reason:" << reason << " called from line:"
386 << line << " when checking:" << nodep << std::endl);
387 // if (debug() >= 9) m_rootp->dumpTree("- root: ");
388 m_failed = true;
389 }
390 return m_failed;
391 }
392 void incrOps(const AstNode* nodep, int line) {
393 ++m_ops;
394 UINFO(9, "Increment to " << m_ops << " " << nodep << " called from line " << line << "\n");
395 }
396 VarInfo& getVarInfo(const LeafInfo& ref) {
397 UASSERT_OBJ(ref.refp(), m_rootp, "null varref in And/Or/Xor optimization");
398 AstNode* nodep = ref.refp()->varScopep();
399 if (!nodep) nodep = ref.refp()->varp(); // Not scoped
400 int baseIdx = nodep->user4();
401 if (baseIdx == 0) { // Not set yet
402 baseIdx = m_varInfos.size();
403 const int numWords
404 = ref.refp()->dtypep()->isWide() ? ref.refp()->dtypep()->widthWords() : 1;
405 m_varInfos.resize(m_varInfos.size() + numWords);
406 nodep->user4(baseIdx);
407 }
408 const size_t idx = baseIdx + std::max(0, ref.wordIdx());
409 VarInfo* varInfop = m_varInfos[idx].get();
410 if (!varInfop) {
411 varInfop = new VarInfo{this, ref.refp(), ref.varWidth()};
412 m_varInfos[idx].reset(varInfop);
413 if (ref.missingWordSel()) {
414 // ConstBitOpTreeVisitor makes some constants for masks and its type is uint64_t.
415 // That's why V3Expand, that inserts WordSel, is needed.
416 CONST_BITOP_SET_FAILED("V3Expand is skipped", ref.refp());
417 }
418 } else {
419 if (!varInfop->sameVarAs(ref.refp()))
420 CONST_BITOP_SET_FAILED("different var (scope?)", ref.refp());
421 }
422 return *varInfop;
423 }
424
425 // Traverse down to see AstConst or AstVarRef
426 LeafInfo findLeaf(AstNode* nodep, bool expectConst) {
427 LeafInfo info{m_lsb};
428 {
429 VL_RESTORER(m_leafp);
430 m_leafp = &info;
431 iterateConst(nodep);
432 }
433
434 bool ok = !m_failed;
435 if (expectConst) {
436 ok &= !info.refp() && info.constp();
437 } else {
438 ok &= info.refp() && !info.constp();
439 }
440 return ok ? info : LeafInfo{};
441 }
442
443 // VISITORS
444 void visit(AstNode* nodep) override { CONST_BITOP_SET_FAILED("Hit unexpected op", nodep); }
445 void visit(AstCCast* nodep) override {
446 iterateChildrenConst(nodep);
447 if (m_leafp) m_leafp->updateBitRange(nodep);
448 }
449 void visit(AstShiftR* nodep) override {
450 CONST_BITOP_RETURN_IF(!m_leafp, nodep);
451 AstConst* const constp = VN_CAST(nodep->rhsp(), Const);
452 CONST_BITOP_RETURN_IF(!constp, nodep->rhsp());
453 m_lsb += constp->toUInt();
454 incrOps(nodep, __LINE__);
455 iterateConst(nodep->lhsp());
456 m_leafp->updateBitRange(nodep);
457 m_lsb -= constp->toUInt();
458 }
459 void visit(AstNot* nodep) override {
460 CONST_BITOP_RETURN_IF(nodep->widthMin() != 1, nodep);
461 AstNode* lhsp = nodep->lhsp();
462 AstCCast* const castp = VN_CAST(lhsp, CCast);
463 if (castp) lhsp = castp->lhsp();
464 CONST_BITOP_RETURN_IF(!isXorTree() && !VN_IS(lhsp, VarRef) && !VN_IS(lhsp, ShiftR), lhsp);
465 incrOps(nodep, __LINE__);
466 m_polarity = !m_polarity;
467 iterateChildrenConst(nodep);
468 // Don't restore m_polarity for Xor as it counts parity of the entire tree
469 if (!isXorTree()) m_polarity = !m_polarity;
470 if (m_leafp && castp) m_leafp->updateBitRange(castp);
471 }
472 void visit(AstWordSel* nodep) override {
473 CONST_BITOP_RETURN_IF(!m_leafp, nodep);
474 AstConst* const constp = VN_CAST(nodep->bitp(), Const);
475 CONST_BITOP_RETURN_IF(!constp, nodep->bitp());
476 UASSERT_OBJ(m_leafp->wordIdx() == -1, nodep, "Unexpected nested WordSel");
477 m_leafp->wordIdx(constp->toSInt());
478 iterateConst(nodep->fromp());
479 }
480 void visit(AstVarRef* nodep) override {
481 CONST_BITOP_RETURN_IF(!m_leafp, nodep);
482 m_leafp->setLeaf(nodep);
483 m_leafp->polarity(m_polarity);
484 }
485 void visit(AstConst* nodep) override {
486 CONST_BITOP_RETURN_IF(!m_leafp, nodep);
487 m_leafp->setLeaf(nodep);
488 }
489
490 void visit(AstRedXor* nodep) override {
491 Restorer restorer{*this};
492 CONST_BITOP_RETURN_IF(!VN_IS(m_rootp, Xor), nodep);
493 AstNode* lhsp = nodep->lhsp();
494 const AstCCast* const castp = VN_CAST(lhsp, CCast);
495 if (castp) lhsp = castp->lhsp();
496 if (const AstAnd* const andp = VN_CAST(lhsp, And)) { // '^(mask & leaf)'
497 CONST_BITOP_RETURN_IF(!andp, lhsp);
498
499 const LeafInfo& mask = findLeaf(andp->lhsp(), true);
500 CONST_BITOP_RETURN_IF(!mask.constp() || mask.lsb() != 0, andp->lhsp());
501
502 LeafInfo ref = findLeaf(andp->rhsp(), false);
503 CONST_BITOP_RETURN_IF(!ref.refp(), andp->rhsp());
504 if (castp) ref.updateBitRange(castp);
505
506 restorer.disableRestore(); // Now all subtree succeeded
507
508 const V3Number& maskNum = mask.constp()->num();
509
510 incrOps(nodep, __LINE__);
511 incrOps(andp, __LINE__);
512
513 // Mark all bits checked in this reduction
514 const int maxBitIdx = std::min(ref.lsb() + maskNum.width(), ref.msb() + 1);
515 for (int bitIdx = ref.lsb(); bitIdx < maxBitIdx; ++bitIdx) {
516 const int maskIdx = bitIdx - ref.lsb();
517 if (maskNum.bitIs0(maskIdx)) continue;
518 // Set true, m_polarity takes care of the entire parity
519 m_bitPolarities.emplace_back(ref, true, bitIdx);
520 }
521 } else { // '^leaf'
522 LeafInfo ref = findLeaf(lhsp, false);
523 CONST_BITOP_RETURN_IF(!ref.refp(), lhsp);
524 if (castp) ref.updateBitRange(castp);
525
526 restorer.disableRestore(); // Now all checks passed
527
528 incrOps(nodep, __LINE__);
529
530 // Mark all bits checked by this comparison
531 for (int bitIdx = ref.lsb(); bitIdx <= ref.msb(); ++bitIdx) {
532 m_bitPolarities.emplace_back(ref, true, bitIdx);
533 }
534 }
535 }
536
537 void visit(AstNodeBiop* nodep) override {
538 if (VN_IS(nodep, And) && isConst(nodep->lhsp(), 1)) { // 1 & _
539 // Always reach past a plain making AND
540 Restorer restorer{*this};
541 incrOps(nodep, __LINE__);
542 iterateConst(nodep->rhsp());
543 CONST_BITOP_RETURN_IF(m_failed, nodep->rhsp());
544 restorer.disableRestore(); // Now all checks passed
545 } else if (nodep->type() == m_rootp->type()) { // And, Or, Xor
546 // subtree under NOT can be optimized only in XOR tree.
547 CONST_BITOP_RETURN_IF(!m_polarity && !isXorTree(), nodep);
548 incrOps(nodep, __LINE__);
549 for (const bool right : {false, true}) {
550 VL_RESTORER(m_leafp);
551 Restorer restorer{*this};
552 LeafInfo leafInfo{m_lsb};
553 // cppcheck-suppress danglingLifetime
554 m_leafp = &leafInfo;
555 AstNodeExpr* opp = right ? nodep->rhsp() : nodep->lhsp();
556 const bool origFailed = m_failed;
557 iterateConst(opp);
558 if (leafInfo.constp() || m_failed) {
559 // Revert changes in leaf
560 restorer.restoreNow();
561 // Reach past a cast then add to frozen nodes to be added to final reduction
562 if (const AstCCast* const castp = VN_CAST(opp, CCast)) opp = castp->lhsp();
563 const bool pol = isXorTree() || m_polarity; // Only AND/OR tree needs polarity
564 UASSERT(pol, "AND/OR tree expects m_polarity==true");
565 m_frozenNodes.emplace_back(opp, FrozenNodeInfo{pol, m_lsb});
566 m_failed = origFailed;
567 continue;
568 }
569 restorer.disableRestore(); // Now all checks passed
570 if (leafInfo.refp()) {
571 // The conditional on the lsb being in range is necessary for some degenerate
572 // case, e.g.: (IData)((QData)wide[0] >> 32), or <1-bit-var> >> 1, which is
573 // just zero
574 if (leafInfo.lsb() <= leafInfo.msb()) {
575 m_bitPolarities.emplace_back(leafInfo, isXorTree() || leafInfo.polarity(),
576 leafInfo.lsb());
577 } else if ((isAndTree() && leafInfo.polarity())
578 || (isOrTree() && !leafInfo.polarity())) {
579 // If there is a constant 0 term in an And tree or 1 term in an Or tree, we
580 // must include it. Fudge this by adding a bit with both polarities, which
581 // will simplify to zero or one respectively.
582 // Note that Xor tree does not need this kind of care, polarity of Xor tree
583 // is already cared when visitin AstNot. Taking xor with 1'b0 is nop.
584 m_bitPolarities.emplace_back(leafInfo, true, 0);
585 m_bitPolarities.emplace_back(leafInfo, false, 0);
586 }
587 }
588 }
589 } else if ((isAndTree() && VN_IS(nodep, Eq)) || (isOrTree() && VN_IS(nodep, Neq))) {
590 Restorer restorer{*this};
591 CONST_BITOP_RETURN_IF(!m_polarity, nodep);
592 CONST_BITOP_RETURN_IF(m_lsb, nodep); // the result of EQ/NE is 1 bit width
593 const AstNode* lhsp = nodep->lhsp();
594 if (const AstCCast* const castp = VN_CAST(lhsp, CCast)) lhsp = castp->lhsp();
595 const AstConst* const constp = VN_CAST(lhsp, Const);
596 CONST_BITOP_RETURN_IF(!constp, nodep->lhsp());
597
598 const V3Number& compNum = constp->num();
599
600 auto setPolarities = [this, &compNum](const LeafInfo& ref, const V3Number* maskp) {
601 const bool maskFlip = isAndTree() ^ ref.polarity();
602 int constantWidth = compNum.width();
603 if (maskp) constantWidth = std::max(constantWidth, maskp->width());
604 const int maxBitIdx = std::max(ref.lsb() + constantWidth, ref.msb() + 1);
605 // Mark all bits checked by this comparison
606 for (int bitIdx = ref.lsb(); bitIdx < maxBitIdx; ++bitIdx) {
607 const int maskIdx = bitIdx - ref.lsb();
608 const bool mask0 = maskp && maskp->bitIs0(maskIdx);
609 const bool outOfRange = bitIdx > ref.msb();
610 if (mask0 || outOfRange) { // RHS is 0
611 if (compNum.bitIs1(maskIdx)) {
612 // LHS is 1
613 // And tree: 1 == 0 => always false, set v && !v
614 // Or tree : 1 != 0 => always true, set v || !v
615 m_bitPolarities.emplace_back(ref, true, 0);
616 m_bitPolarities.emplace_back(ref, false, 0);
617 break;
618 } else { // This bitIdx is irrelevant
619 continue;
620 }
621 }
622 const bool polarity = compNum.bitIs1(maskIdx) != maskFlip;
623 m_bitPolarities.emplace_back(ref, polarity, bitIdx);
624 }
625 };
626
627 if (const AstAnd* const andp = VN_CAST(nodep->rhsp(), And)) { // comp == (mask & v)
628 const LeafInfo& mask = findLeaf(andp->lhsp(), true);
629 CONST_BITOP_RETURN_IF(!mask.constp() || mask.lsb() != 0, andp->lhsp());
630
631 const LeafInfo& ref = findLeaf(andp->rhsp(), false);
632 CONST_BITOP_RETURN_IF(!ref.refp(), andp->rhsp());
633
634 restorer.disableRestore(); // Now all checks passed
635
636 const V3Number& maskNum = mask.constp()->num();
637
638 incrOps(nodep, __LINE__);
639 incrOps(andp, __LINE__);
640
641 setPolarities(ref, &maskNum);
642 } else { // comp == v
643 const LeafInfo& ref = findLeaf(nodep->rhsp(), false);
644 CONST_BITOP_RETURN_IF(!ref.refp(), nodep->rhsp());
645
646 restorer.disableRestore(); // Now all checks passed
647
648 incrOps(nodep, __LINE__);
649
650 setPolarities(ref, nullptr);
651 }
652 } else {
653 CONST_BITOP_SET_FAILED("Mixture of different ops cannot be optimized", nodep);
654 }
655 }
656
657 // CONSTRUCTORS
658 ConstBitOpTreeVisitor(AstNodeExpr* nodep, unsigned externalOps)
659 : m_ops{externalOps}
660 , m_rootp{nodep} {
661 // Fill nullptr at [0] because AstVarScope::user4 is 0 by default
662 m_varInfos.push_back(nullptr);
663 CONST_BITOP_RETURN_IF(!isAndTree() && !isOrTree() && !isXorTree(), nodep);
664 if (AstNodeBiop* const biopp = VN_CAST(nodep, NodeBiop)) {
665 iterateConst(biopp);
666 } else {
667 UASSERT_OBJ(VN_IS(nodep, RedXor), nodep, "Must be RedXor");
668 incrOps(nodep, __LINE__);
669 iterateChildrenConst(nodep);
670 }
671 for (auto&& entry : m_bitPolarities) {
672 getVarInfo(entry.m_info).setPolarity(entry.m_polarity, entry.m_bit);
673 }
674 UASSERT_OBJ(isXorTree() || m_polarity, nodep, "must be the original polarity");
675 }
676 virtual ~ConstBitOpTreeVisitor() = default;
677 #undef CONST_BITOP_RETURN_IF
678 #undef CONST_BITOP_SET_FAILED
679
680 public:
681 // Transform as below.
682 // v[0] & v[1] => 2'b11 == (2'b11 & v)
683 // v[0] | v[1] => 2'b00 != (2'b11 & v)
684 // v[0] ^ v[1] => ^{2'b11 & v}
685 // (3'b011 == (3'b011 & v)) & v[2] => 3'b111 == (3'b111 & v)
686 // (3'b000 != (3'b011 & v)) | v[2] => 3'b000 != (3'b111 & v)
687 // Reduction ops are transformed in the same way.
688 // &{v[0], v[1]} => 2'b11 == (2'b11 & v)
689 static AstNodeExpr* simplify(AstNodeExpr* nodep, int resultWidth, unsigned externalOps,
690 VDouble0& reduction) {
691 UASSERT_OBJ(1 <= resultWidth && resultWidth <= 64, nodep, "resultWidth out of range");
692
693 // Walk tree, gathering all terms referenced in expression
694 const ConstBitOpTreeVisitor visitor{nodep, externalOps};
695
696 // If failed on root node is not optimizable, or there are no variable terms, then done
697 if (visitor.m_failed || visitor.m_varInfos.size() == 1) return nullptr;
698
699 // FileLine used for constructing all new nodes in this function
700 FileLine* const fl = nodep->fileline();
701
702 // Get partial result each term referenced, count total number of ops and keep track of
703 // whether we have clean/dirty terms. visitor.m_varInfos appears in deterministic order,
704 // so the optimized tree is deterministic as well.
705
706 std::vector<AstNodeExpr*> termps;
707 termps.reserve(visitor.m_varInfos.size() - 1);
708 unsigned resultOps = 0;
709 bool hasCleanTerm = false;
710 bool hasDirtyTerm = false;
711
712 for (auto&& v : visitor.m_varInfos) {
713 if (!v) continue; // Skip nullptr at m_varInfos[0]
714 if (v->hasConstResult()) {
715 // If a constant term is known, we can either drop it or the whole tree is constant
716 AstNodeExpr* resultp = nullptr;
717 if (v->getConstResult()) {
718 UASSERT_OBJ(visitor.isOrTree(), nodep,
719 "Only OR tree can yield known 1 result");
720 UINFO(9, "OR tree with const 1 term: " << v->refp() << endl);
721 // Known 1 bit in OR tree, whole result is 1
722 resultp = new AstConst{fl, AstConst::BitTrue{}};
723 } else if (visitor.isAndTree()) {
724 UINFO(9, "AND tree with const 0 term: " << v->refp() << endl);
725 // Known 0 bit in AND tree, whole result is 0
726 resultp = new AstConst{fl, AstConst::BitFalse{}};
727 } else {
728 // Known 0 bit in OR or XOR tree. Ignore it.
729 continue;
730 }
731 // Set width and widthMin precisely
732 resultp->dtypeChgWidth(resultWidth, 1);
733 for (AstNode* const termp : termps) VL_DO_DANGLING(termp->deleteTree(), termp);
734 return resultp;
735 }
736 const ResultTerm result = v->getResultTerm();
737 termps.push_back(std::get<0>(result));
738 resultOps += std::get<1>(result);
739 if (std::get<2>(result)) {
740 hasCleanTerm = true;
741 UINFO(9, "Clean term: " << termps.back() << endl);
742 } else {
743 hasDirtyTerm = true;
744 UINFO(9, "Dirty term: " << termps.back() << endl);
745 }
746 }
747
748 // Group by FrozenNodeInfo
749 std::map<FrozenNodeInfo, std::vector<AstNodeExpr*>> frozenNodes;
750 // Check if frozen terms are clean or not
751 for (const auto& frozenInfo : visitor.m_frozenNodes) {
752 AstNodeExpr* const termp = frozenInfo.first;
753 // Comparison operators are clean
754 if ((VN_IS(termp, Eq) || VN_IS(termp, Neq) || VN_IS(termp, Lt) || VN_IS(termp, Lte)
755 || VN_IS(termp, Gt) || VN_IS(termp, Gte))
756 && frozenInfo.second.m_lsb == 0) {
757 hasCleanTerm = true;
758 } else {
759 // Otherwise, conservatively assume the frozen term is dirty
760 hasDirtyTerm = true;
761 UINFO(9, "Dirty frozen term: " << termp << endl);
762 }
763 frozenNodes[frozenInfo.second].push_back(termp);
764 }
765
766 // Figure out if a final negation is required
767 const bool needsFlip = visitor.isXorTree() && !visitor.m_polarity;
768
769 // Figure out if the final tree needs cleaning
770 const bool needsCleaning = visitor.isAndTree() ? !hasCleanTerm : hasDirtyTerm;
771
772 // Add size of reduction tree to op count
773 resultOps += termps.size() - 1;
774 for (const auto& lsbAndNodes : frozenNodes) {
775 if (lsbAndNodes.first.m_lsb > 0) ++resultOps; // Needs AstShiftR
776 if (!lsbAndNodes.first.m_polarity) ++resultOps; // Needs AstNot
777 resultOps += lsbAndNodes.second.size();
778 }
779 // Add final polarity flip in Xor tree
780 if (needsFlip) ++resultOps;
781 // Add final cleaning AND
782 if (needsCleaning) ++resultOps;
783
784 if (debug() >= 9) { // LCOV_EXCL_START
785 cout << "- Bitop tree considered:\n";
786 for (AstNodeExpr* const termp : termps) termp->dumpTree("- Reduced term: ");
787 for (const std::pair<AstNodeExpr*, FrozenNodeInfo>& termp : visitor.m_frozenNodes) {
788 termp.first->dumpTree("- Frozen term with lsb "
789 + std::to_string(termp.second.m_lsb) + " polarity "
790 + std::to_string(termp.second.m_polarity) + ": ");
791 }
792 cout << "- Needs flipping: " << needsFlip << "\n";
793 cout << "- Needs cleaning: " << needsCleaning << "\n";
794 cout << "- Size: " << resultOps << " input size: " << visitor.m_ops << "\n";
795 } // LCOV_EXCL_END
796
797 // Sometimes we have no terms left after ignoring redundant terms
798 // (all of which were zeroes)
799 if (termps.empty() && visitor.m_frozenNodes.empty()) {
800 reduction += visitor.m_ops;
801 AstNodeExpr* const resultp = needsFlip ? new AstConst{fl, AstConst::BitTrue{}}
802 : new AstConst{fl, AstConst::BitFalse{}};
803 resultp->dtypeChgWidth(resultWidth, 1);
804 return resultp;
805 }
806
807 // Only substitute the result if beneficial as determined by operation count
808 if (visitor.m_ops <= resultOps) {
809 for (AstNode* const termp : termps) VL_DO_DANGLING(termp->deleteTree(), termp);
810 return nullptr;
811 }
812
813 // Update statistics
814 reduction += visitor.m_ops - resultOps;
815
816 // Reduction op to combine terms
817 const auto reduce = [&visitor, fl](AstNodeExpr* lhsp, AstNodeExpr* rhsp) -> AstNodeExpr* {
818 if (!lhsp) return rhsp;
819 if (visitor.isAndTree()) {
820 return new AstAnd{fl, lhsp, rhsp};
821 } else if (visitor.isOrTree()) {
822 return new AstOr{fl, lhsp, rhsp};
823 } else {
824 return new AstXor{fl, lhsp, rhsp};
825 }
826 };
827
828 // Compute result by reducing all terms
829 AstNodeExpr* resultp = nullptr;
830 for (AstNodeExpr* const termp : termps) { //
831 resultp = reduce(resultp, termp);
832 }
833 // Add any frozen terms to the reduction
834 for (auto&& nodes : frozenNodes) {
835 // nodes.second has same lsb and polarity
836 AstNodeExpr* termp = nullptr;
837 for (AstNodeExpr* const itemp : nodes.second) {
838 termp = reduce(termp, itemp->unlinkFrBack());
839 }
840 if (nodes.first.m_lsb > 0) { // LSB is not 0, so shiftR
841 AstNodeDType* const dtypep = termp->dtypep();
842 termp = new AstShiftR{termp->fileline(), termp,
843 new AstConst(termp->fileline(), AstConst::WidthedValue{},
844 termp->width(), nodes.first.m_lsb)};
845 termp->dtypep(dtypep);
846 }
847 if (!nodes.first.m_polarity) { // Polarity is inverted, so append Not
848 AstNodeDType* const dtypep = termp->dtypep();
849 termp = new AstNot{termp->fileline(), termp};
850 termp->dtypep(dtypep);
851 }
852 resultp = reduce(resultp, termp);
853 }
854
855 // Set width of masks to expected result width. This is required to prevent later removal
856 // of the masking node e.g. by the "AND with all ones" rule. If the result width happens
857 // to be 1, we still need to ensure the AstAnd is not dropped, so use a wider mask in this
858 // special case.
859 const int maskWidth
860 = std::max(resultp->width(), resultWidth == 1 ? VL_IDATASIZE : resultWidth);
861
862 // Apply final polarity flip
863 if (needsFlip) {
864 if (needsCleaning) {
865 // Cleaning will be added below. Use a NOT which is a byte shorter on x86
866 resultp = new AstNot{fl, resultp};
867 } else {
868 // Keep result clean by using XOR(1, _)
869 AstConst* const maskp = new AstConst{fl, AstConst::WidthedValue{}, maskWidth, 1};
870 resultp = new AstXor{fl, maskp, resultp};
871 }
872 }
873
874 // Apply final cleaning
875 if (needsCleaning) {
876 AstConst* const maskp = new AstConst{fl, AstConst::WidthedValue{}, maskWidth, 1};
877 resultp = new AstAnd{fl, maskp, resultp};
878 }
879
880 // Cast back to original size if required
881 if (resultp->width() != resultWidth) {
882 resultp = new AstCCast{fl, resultp, resultWidth, 1};
883 }
884
885 // Set width and widthMin precisely
886 resultp->dtypeChgWidth(resultWidth, 1);
887
888 return resultp;
889 }
890 };
891
892 //######################################################################
893 // Const state, as a visitor of each AstNode
894
895 class ConstVisitor final : public VNVisitor {
896 // CONSTANTS
897 static constexpr unsigned CONCAT_MERGABLE_MAX_DEPTH = 10; // Limit alg recursion
898
899 // NODE STATE
900 // ** only when m_warn/m_doExpensive is set. If state is needed other times,
901 // ** must track down everywhere V3Const is called and make sure no overlaps.
902 // AstVar::user4p -> Used by variable marking/finding
903 // AstJumpLabel::user4 -> bool. Set when AstJumpGo uses this label
904 // AstEnum::user4 -> bool. Recursing.
905
906 // STATE
907 static constexpr bool m_doShort = true; // Remove expressions that short circuit
908 bool m_params = false; // If true, propagate parameterized and true numbers only
909 bool m_required = false; // If true, must become a constant
910 bool m_wremove = true; // Inside scope, no assignw removal
911 bool m_warn = false; // Output warnings
912 bool m_doExpensive = false; // Enable computationally expensive optimizations
913 bool m_doCpp = false; // Enable late-stage C++ optimizations
914 bool m_doNConst = false; // Enable non-constant-child simplifications
915 bool m_doV = false; // Verilog, not C++ conversion
916 bool m_doGenerate = false; // Postpone width checking inside generate
917 bool m_convertLogicToBit = false; // Convert logical operators to bitwise
918 bool m_hasJumpDelay = false; // JumpGo or Delay under this while
919 bool m_underRecFunc = false; // Under a recursive function
920 AstNodeModule* m_modp = nullptr; // Current module
921 const AstArraySel* m_selp = nullptr; // Current select
922 const AstNode* m_scopep = nullptr; // Current scope
923 const AstAttrOf* m_attrp = nullptr; // Current attribute
924 VDouble0 m_statBitOpReduction; // Ops reduced in ConstBitOpTreeVisitor
925 const bool m_globalPass; // ConstVisitor invoked as a global pass
926 static uint32_t s_globalPassNum; // Counts number of times ConstVisitor invoked as global pass
927 V3UniqueNames m_concswapNames; // For generating unique temporary variable names
928 std::map<const AstNode*, bool> m_containsMemberAccess; // Caches results of matchBiopToBitwise
929
930 // METHODS
931
932 bool operandConst(AstNode* nodep) { return VN_IS(nodep, Const); }
933 bool operandAsvConst(const AstNode* nodep) {
934 // BIASV(CONST, BIASV(CONST,...)) -> BIASV( BIASV_CONSTED(a,b), ...)
935 const AstNodeBiComAsv* const bnodep = VN_CAST(nodep, NodeBiComAsv);
936 if (!bnodep) return false;
937 if (!VN_IS(bnodep->lhsp(), Const)) return false;
938 const AstNodeBiComAsv* const rnodep = VN_CAST(bnodep->rhsp(), NodeBiComAsv);
939 if (!rnodep) return false;
940 if (rnodep->type() != bnodep->type()) return false;
941 if (rnodep->width() != bnodep->width()) return false;
942 if (rnodep->lhsp()->width() != bnodep->lhsp()->width()) return false;
943 if (!VN_IS(rnodep->lhsp(), Const)) return false;
944 return true;
945 }
946 bool operandAsvSame(const AstNode* nodep) {
947 // BIASV(SAMEa, BIASV(SAMEb,...)) -> BIASV( BIASV(SAMEa,SAMEb), ...)
948 const AstNodeBiComAsv* const bnodep = VN_CAST(nodep, NodeBiComAsv);
949 if (!bnodep) return false;
950 const AstNodeBiComAsv* const rnodep = VN_CAST(bnodep->rhsp(), NodeBiComAsv);
951 if (!rnodep) return false;
952 if (rnodep->type() != bnodep->type()) return false;
953 if (rnodep->width() != bnodep->width()) return false;
954 return operandsSame(bnodep->lhsp(), rnodep->lhsp());
955 }
956 bool operandAsvLUp(const AstNode* nodep) {
957 // BIASV(BIASV(CONSTll,lr),r) -> BIASV(CONSTll,BIASV(lr,r)) ?
958 //
959 // Example of how this is useful:
960 // BIASV(BIASV(CONSTa,b...),BIASV(CONSTc,d...)) // hits operandAsvUp
961 // BIASV(CONSTa,BIASV(b...,BIASV(CONSTc,d...))) // hits operandAsvUp
962 // BIASV(CONSTa,BIASV(CONSTc,BIASV(c...,d...))) // hits operandAsvConst
963 // BIASV(BIASV(CONSTa,CONSTc),BIASV(c...,d...))) // hits normal constant propagation
964 // BIASV(CONST_a_c,BIASV(c...,d...)))
965 //
966 // Idea for the future: All BiComAsvs could be lists, sorted by if they're constant
967 const AstNodeBiComAsv* const bnodep = VN_CAST(nodep, NodeBiComAsv);
968 if (!bnodep) return false;
969 const AstNodeBiComAsv* const lnodep = VN_CAST(bnodep->lhsp(), NodeBiComAsv);
970 if (!lnodep) return false;
971 if (lnodep->type() != bnodep->type()) return false;
972 if (lnodep->width() != bnodep->width()) return false;
973 return VN_IS(lnodep->lhsp(), Const);
974 }
975 bool operandAsvRUp(const AstNode* nodep) {
976 // BIASV(l,BIASV(CONSTrl,rr)) -> BIASV(CONSTrl,BIASV(l,rr)) ?
977 const AstNodeBiComAsv* const bnodep = VN_CAST(nodep, NodeBiComAsv);
978 if (!bnodep) return false;
979 const AstNodeBiComAsv* const rnodep = VN_CAST(bnodep->rhsp(), NodeBiComAsv);
980 if (!rnodep) return false;
981 if (rnodep->type() != bnodep->type()) return false;
982 if (rnodep->width() != bnodep->width()) return false;
983 return VN_IS(rnodep->lhsp(), Const);
984 }
985 static bool operandSubAdd(const AstNode* nodep) {
986 // SUB( ADD(CONSTx,y), CONSTz) -> ADD(SUB(CONSTx,CONSTz), y)
987 const AstNodeBiop* const np = VN_CAST(nodep, NodeBiop);
988 const AstNodeBiop* const lp = VN_CAST(np->lhsp(), NodeBiop);
989 return (lp && VN_IS(lp->lhsp(), Const) && VN_IS(np->rhsp(), Const)
990 && lp->width() == np->width());
991 }
992 bool matchRedundantClean(AstAnd* andp) {
993 // Remove And with constant one inserted by V3Clean
994 // 1 & (a == b) -> (IData)(a == b)
995 // When bool is casted to int, the value is either 0 or 1
996 AstConst* const constp = VN_AS(andp->lhsp(), Const);
997 UASSERT_OBJ(constp && constp->isOne(), andp->lhsp(), "TRREEOPC must meet this condition");
998 AstNodeExpr* const rhsp = andp->rhsp();
999 AstCCast* ccastp = nullptr;
1000 const auto isEqOrNeq
1001 = [](AstNode* nodep) -> bool { return VN_IS(nodep, Eq) || VN_IS(nodep, Neq); };
1002 if (isEqOrNeq(rhsp)) {
1003 ccastp = new AstCCast{andp->fileline(), rhsp->unlinkFrBack(), andp};
1004 } else if (AstCCast* const tmpp = VN_CAST(rhsp, CCast)) {
1005 if (isEqOrNeq(tmpp->lhsp())) {
1006 if (tmpp->width() == andp->width()) {
1007 tmpp->unlinkFrBack();
1008 ccastp = tmpp;
1009 } else {
1010 ccastp = new AstCCast{andp->fileline(), tmpp->lhsp()->unlinkFrBack(), andp};
1011 }
1012 }
1013 }
1014 if (ccastp) {
1015 andp->replaceWith(ccastp);
1016 VL_DO_DANGLING(pushDeletep(andp), andp);
1017 return true;
1018 }
1019 return false;
1020 }
1021
1022 static bool operandAndOrSame(const AstNode* nodep) {
1023 // OR( AND(VAL,x), AND(VAL,y)) -> AND(VAL,OR(x,y))
1024 // OR( AND(x,VAL), AND(y,VAL)) -> AND(OR(x,y),VAL)
1025 const AstNodeBiop* const np = VN_CAST(nodep, NodeBiop);
1026 const AstNodeBiop* const lp = VN_CAST(np->lhsp(), NodeBiop);
1027 const AstNodeBiop* const rp = VN_CAST(np->rhsp(), NodeBiop);
1028 return (lp && rp && lp->width() == rp->width() && lp->type() == rp->type()
1029 && (operandsSame(lp->lhsp(), rp->lhsp()) || operandsSame(lp->rhsp(), rp->rhsp())));
1030 }
1031 bool matchOrAndNot(AstNodeBiop* nodep) {
1032 // AstOr{$a, AstAnd{AstNot{$b}, $c}} if $a.width1, $a==$b => AstOr{$a,$c}
1033 // Someday we'll sort the biops completely and this can be simplified
1034 // This often results from our simplified clock generation:
1035 // if (rst) ... else if (enable)... -> OR(rst,AND(!rst,enable))
1036 AstNodeExpr* ap;
1037 AstNodeBiop* andp;
1038 if (VN_IS(nodep->lhsp(), And)) {
1039 andp = VN_AS(nodep->lhsp(), And);
1040 ap = nodep->rhsp();
1041 } else if (VN_IS(nodep->rhsp(), And)) {
1042 andp = VN_AS(nodep->rhsp(), And);
1043 ap = nodep->lhsp();
1044 } else {
1045 return false;
1046 }
1047 const AstNodeUniop* notp;
1048 AstNodeExpr* cp;
1049 if (VN_IS(andp->lhsp(), Not)) {
1050 notp = VN_AS(andp->lhsp(), Not);
1051 cp = andp->rhsp();
1052 } else if (VN_IS(andp->rhsp(), Not)) {
1053 notp = VN_AS(andp->rhsp(), Not);
1054 cp = andp->lhsp();
1055 } else {
1056 return false;
1057 }
1058 AstNodeExpr* const bp = notp->lhsp();
1059 if (!operandsSame(ap, bp)) return false;
1060 // Do it
1061 cp->unlinkFrBack();
1062 VL_DO_DANGLING(pushDeletep(andp->unlinkFrBack()), andp);
1063 VL_DANGLING(notp);
1064 // Replace whichever branch is now dangling
1065 if (nodep->rhsp()) {
1066 nodep->lhsp(cp);
1067 } else {
1068 nodep->rhsp(cp);
1069 }
1070 return true;
1071 }
1072 bool matchAndCond(AstAnd* nodep) {
1073 // Push down a AND into conditional, when one side of conditional is constant
1074 // (otherwise we'd be trading one operation for two operations)
1075 // V3Clean often makes this pattern, as it postpones the AND until
1076 // as high as possible, which is usually the right choice, except for this.
1077 AstNodeCond* const condp = VN_CAST(nodep->rhsp(), NodeCond);
1078 if (!condp) return false;
1079 if (!VN_IS(condp->thenp(), Const) && !VN_IS(condp->elsep(), Const)) return false;
1080 AstConst* const maskp = VN_CAST(nodep->lhsp(), Const);
1081 if (!maskp) return false;
1082 UINFO(4, "AND(CONSTm, CONDcond(c, i, e))->CONDcond(c, AND(m,i), AND(m, e)) " << nodep
1083 << endl);
1084 AstNodeCond* const newp = static_cast<AstNodeCond*>(condp->cloneType(
1085 condp->condp()->unlinkFrBack(),
1086 new AstAnd{nodep->fileline(), maskp->cloneTree(false), condp->thenp()->unlinkFrBack()},
1087 new AstAnd{nodep->fileline(), maskp->cloneTree(false),
1088 condp->elsep()->unlinkFrBack()}));
1089 newp->dtypeFrom(nodep);
1090 newp->thenp()->dtypeFrom(nodep); // As And might have been to change widths
1091 newp->elsep()->dtypeFrom(nodep);
1092 nodep->replaceWith(newp);
1093 VL_DO_DANGLING(pushDeletep(nodep), nodep);
1094 return true;
1095 }
1096 bool matchMaskedOr(AstAnd* nodep) {
1097 // Masking an OR with terms that have no bits set under the mask is replaced with masking
1098 // only the remaining terms. Canonical example as generated by V3Expand is:
1099 // 0xff & (a << 8 | b >> 24) --> 0xff & (b >> 24)
1100
1101 // Compute how many significant bits are in the mask
1102 const AstConst* const constp = VN_AS(nodep->lhsp(), Const);
1103 const uint32_t significantBits = constp->num().widthMin();
1104
1105 AstOr* const orp = VN_AS(nodep->rhsp(), Or);
1106
1107 // Predicate for checking whether the bottom 'significantBits' bits of the given expression
1108 // are all zeroes.
1109 const auto checkBottomClear = [=](const AstNode* nodep) -> bool {
1110 if (const AstShiftL* const shiftp = VN_CAST(nodep, ShiftL)) {
1111 if (const AstConst* const scp = VN_CAST(shiftp->rhsp(), Const)) {
1112 return scp->num().toUInt() >= significantBits;
1113 }
1114 }
1115 return false;
1116 };
1117
1118 const bool orLIsRedundant = checkBottomClear(orp->lhsp());
1119 const bool orRIsRedundant = checkBottomClear(orp->rhsp());
1120
1121 if (orLIsRedundant && orRIsRedundant) {
1122 nodep->replaceWith(
1123 new AstConst{nodep->fileline(), AstConst::DTyped{}, nodep->dtypep()});
1124 VL_DO_DANGLING(pushDeletep(nodep), nodep);
1125 return true;
1126 } else if (orLIsRedundant) {
1127 orp->replaceWith(orp->rhsp()->unlinkFrBack());
1128 VL_DO_DANGLING(pushDeletep(orp), orp);
1129 return false; // input node is still valid, keep going
1130 } else if (orRIsRedundant) {
1131 orp->replaceWith(orp->lhsp()->unlinkFrBack());
1132 VL_DO_DANGLING(pushDeletep(orp), orp);
1133 return false; // input node is still valid, keep going
1134 } else {
1135 return false;
1136 }
1137 }
1138 bool matchMaskedShift(AstAnd* nodep) {
1139 // Drop redundant masking of right shift result. E.g: 0xff & ((uint32_t)a >> 24). This
1140 // commonly appears after V3Expand and the simplification in matchMaskedOr. Similarly,
1141 // drop redundant masking of left shift result. E.g.: 0xff000000 & ((uint32_t)a << 24).
1142
1143 const auto checkMask = [nodep, this](const V3Number& mask) -> bool {
1144 const AstConst* const constp = VN_AS(nodep->lhsp(), Const);
1145 if (constp->num().isCaseEq(mask)) {
1146 AstNode* const rhsp = nodep->rhsp();
1147 rhsp->unlinkFrBack();
1148 nodep->replaceWith(rhsp);
1149 rhsp->dtypeFrom(nodep);
1150 VL_DO_DANGLING(pushDeletep(nodep), nodep);
1151 return true;
1152 }
1153 return false;
1154 };
1155
1156 // Check if masking is redundant
1157 if (const AstShiftR* const shiftp = VN_CAST(nodep->rhsp(), ShiftR)) {
1158 if (const AstConst* const scp = VN_CAST(shiftp->rhsp(), Const)) {
1159 // Check if mask is full over the non-zero bits
1160 V3Number maskLo{nodep, nodep->width()};
1161 maskLo.setMask(nodep->width() - scp->num().toUInt());
1162 return checkMask(maskLo);
1163 }
1164 } else if (const AstShiftL* const shiftp = VN_CAST(nodep->rhsp(), ShiftL)) {
1165 if (const AstConst* const scp = VN_CAST(shiftp->rhsp(), Const)) {
1166 // Check if mask is full over the non-zero bits
1167 V3Number mask{nodep, nodep->width()};
1168 const uint32_t shiftAmount = scp->num().toUInt();
1169 mask.setMask(nodep->width() - shiftAmount, shiftAmount);
1170 return checkMask(mask);
1171 }
1172 }
1173 return false;
1174 }
1175
1176 bool matchBitOpTree(AstNodeExpr* nodep) {
1177 if (nodep->widthMin() != 1) return false;
1178 if (!v3Global.opt.fConstBitOpTree()) return false;
1179
1180 string debugPrefix;
1181 if (debug() >= 9) { // LCOV_EXCL_START
1182 static int c = 0;
1183 debugPrefix = "- matchBitOpTree[";
1184 debugPrefix += cvtToStr(++c);
1185 debugPrefix += "] ";
1186 nodep->dumpTree(debugPrefix + "INPUT: ");
1187 } // LCOV_EXCL_STOP
1188
1189 AstNode* newp = nullptr;
1190 const AstAnd* const andp = VN_CAST(nodep, And);
1191 const int width = nodep->width();
1192 if (andp && isConst(andp->lhsp(), 1)) { // 1 & BitOpTree
1193 newp = ConstBitOpTreeVisitor::simplify(andp->rhsp(), width, 1, m_statBitOpReduction);
1194 } else { // BitOpTree
1195 newp = ConstBitOpTreeVisitor::simplify(nodep, width, 0, m_statBitOpReduction);
1196 }
1197
1198 if (newp) {
1199 UINFO(4, "Transformed leaf of bit tree to " << newp << std::endl);
1200 nodep->replaceWith(newp);
1201 VL_DO_DANGLING(pushDeletep(nodep), nodep);
1202 }
1203
1204 if (debug() >= 9) { // LCOV_EXCL_START
1205 if (newp) {
1206 newp->dumpTree(debugPrefix + "RESULT: ");
1207 } else {
1208 cout << debugPrefix << "not replaced" << endl;
1209 }
1210 } // LCOV_EXCL_STOP
1211
1212 return newp;
1213 }
1214 static bool operandShiftSame(const AstNode* nodep) {
1215 const AstNodeBiop* const np = VN_AS(nodep, NodeBiop);
1216 {
1217 const AstShiftL* const lp = VN_CAST(np->lhsp(), ShiftL);
1218 const AstShiftL* const rp = VN_CAST(np->rhsp(), ShiftL);
1219 if (lp && rp) {
1220 return (lp->width() == rp->width() && lp->lhsp()->width() == rp->lhsp()->width()
1221 && operandsSame(lp->rhsp(), rp->rhsp()));
1222 }
1223 }
1224 {
1225 const AstShiftR* const lp = VN_CAST(np->lhsp(), ShiftR);
1226 const AstShiftR* const rp = VN_CAST(np->rhsp(), ShiftR);
1227 if (lp && rp) {
1228 return (lp->width() == rp->width() && lp->lhsp()->width() == rp->lhsp()->width()
1229 && operandsSame(lp->rhsp(), rp->rhsp()));
1230 }
1231 }
1232 return false;
1233 }
1234 bool operandHugeShiftL(const AstNodeBiop* nodep) {
1235 return (VN_IS(nodep->rhsp(), Const) && !VN_AS(nodep->rhsp(), Const)->num().isFourState()
1236 && (!VN_AS(nodep->rhsp(), Const)->num().fitsInUInt() // > 2^32 shift
1237 || (VN_AS(nodep->rhsp(), Const)->toUInt()
1238 >= static_cast<uint32_t>(nodep->width())))
1239 && nodep->lhsp()->isPure());
1240 }
1241 bool operandHugeShiftR(const AstNodeBiop* nodep) {
1242 return (VN_IS(nodep->rhsp(), Const) && !VN_AS(nodep->rhsp(), Const)->num().isFourState()
1243 && (!VN_AS(nodep->rhsp(), Const)->num().fitsInUInt() // > 2^32 shift
1244 || (VN_AS(nodep->rhsp(), Const)->toUInt()
1245 >= static_cast<uint32_t>(nodep->lhsp()->width())))
1246 && nodep->lhsp()->isPure());
1247 }
1248 bool operandIsTwo(const AstNode* nodep) {
1249 return (VN_IS(nodep, Const) && !VN_AS(nodep, Const)->num().isFourState()
1250 && nodep->width() <= VL_QUADSIZE && VN_AS(nodep, Const)->toUQuad() == 2);
1251 }
1252 bool operandIsTwostate(const AstNode* nodep) {
1253 return (VN_IS(nodep, Const) && !VN_AS(nodep, Const)->num().isFourState());
1254 }
1255 bool operandIsPowTwo(const AstNode* nodep) {
1256 if (!operandIsTwostate(nodep)) return false;
1257 return (1 == VN_AS(nodep, Const)->num().countOnes());
1258 }
1259 bool operandShiftOp(const AstNodeBiop* nodep) {
1260 if (!VN_IS(nodep->rhsp(), Const)) return false;
1261 const AstNodeBiop* const lhsp = VN_CAST(nodep->lhsp(), NodeBiop);
1262 if (!lhsp || !(VN_IS(lhsp, And) || VN_IS(lhsp, Or) || VN_IS(lhsp, Xor))) return false;
1263 if (nodep->width() != lhsp->width()) return false;
1264 if (nodep->width() != lhsp->lhsp()->width()) return false;
1265 if (nodep->width() != lhsp->rhsp()->width()) return false;
1266 return true;
1267 }
1268 bool operandShiftShift(const AstNodeBiop* nodep) {
1269 // We could add a AND though.
1270 const AstNodeBiop* const lhsp = VN_CAST(nodep->lhsp(), NodeBiop);
1271 if (!lhsp || !(VN_IS(lhsp, ShiftL) || VN_IS(lhsp, ShiftR))) return false;
1272 // We can only get rid of a<<b>>c or a<<b<<c, with constant b & c
1273 // because bits may be masked in that process, or (b+c) may exceed the word width.
1274 if (!(VN_IS(nodep->rhsp(), Const) && VN_IS(lhsp->rhsp(), Const))) return false;
1275 if (VN_AS(nodep->rhsp(), Const)->num().isFourState()
1276 || VN_AS(lhsp->rhsp(), Const)->num().isFourState())
1277 return false;
1278 if (nodep->width() != lhsp->width()) return false;
1279 if (nodep->width() != lhsp->lhsp()->width()) return false;
1280 return true;
1281 }
1282 bool operandWordOOB(const AstWordSel* nodep) {
1283 // V3Expand may make a arraysel that exceeds the bounds of the array
1284 // It was an expression, then got constified. In reality, the WordSel
1285 // must be wrapped in a Cond, that will be false.
1286 return (VN_IS(nodep->bitp(), Const) && VN_IS(nodep->fromp(), NodeVarRef)
1287 && VN_AS(nodep->fromp(), NodeVarRef)->access().isReadOnly()
1288 && (static_cast<int>(VN_AS(nodep->bitp(), Const)->toUInt())
1289 >= VN_AS(nodep->fromp(), NodeVarRef)->varp()->widthWords()));
1290 }
1291 bool operandSelFull(const AstSel* nodep) {
1292 return (VN_IS(nodep->lsbp(), Const) && VN_IS(nodep->widthp(), Const)
1293 && nodep->lsbConst() == 0
1294 && static_cast<int>(nodep->widthConst()) == nodep->fromp()->width());
1295 }
1296 bool operandSelExtend(AstSel* nodep) {
1297 // A pattern created by []'s after offsets have been removed
1298 // SEL(EXTEND(any,width,...),(width-1),0) -> ...
1299 // Since select's return unsigned, this is always an extend
1300 AstExtend* const extendp = VN_CAST(nodep->fromp(), Extend);
1301 if (!(m_doV && extendp && VN_IS(nodep->lsbp(), Const) && VN_IS(nodep->widthp(), Const)
1302 && nodep->lsbConst() == 0
1303 && static_cast<int>(nodep->widthConst()) == extendp->lhsp()->width()))
1304 return false;
1305 VL_DO_DANGLING(replaceWChild(nodep, extendp->lhsp()), nodep);
1306 return true;
1307 }
1308 bool operandSelBiLower(AstSel* nodep) {
1309 // SEL(ADD(a,b),(width-1),0) -> ADD(SEL(a),SEL(b))
1310 // Add or any operation which doesn't care if we discard top bits
1311 AstNodeBiop* const bip = VN_CAST(nodep->fromp(), NodeBiop);
1312 if (!(m_doV && bip && VN_IS(nodep->lsbp(), Const) && VN_IS(nodep->widthp(), Const)
1313 && nodep->lsbConst() == 0))
1314 return false;
1315 if (debug() >= 9) nodep->dumpTree("- SEL(BI)-in: ");
1316 AstNodeExpr* const bilhsp = bip->lhsp()->unlinkFrBack();
1317 AstNodeExpr* const birhsp = bip->rhsp()->unlinkFrBack();
1318 bip->lhsp(new AstSel{nodep->fileline(), bilhsp, 0, nodep->widthConst()});
1319 bip->rhsp(new AstSel{nodep->fileline(), birhsp, 0, nodep->widthConst()});
1320 if (debug() >= 9) bip->dumpTree("- SEL(BI)-ou: ");
1321 VL_DO_DANGLING(replaceWChild(nodep, bip), nodep);
1322 return true;
1323 }
1324 bool operandSelShiftLower(AstSel* nodep) {
1325 // AND({a}, SHIFTR({b}, {c})) is often shorthand in C for Verilog {b}[{c} :+ {a}]
1326 // becomes thought other optimizations
1327 // SEL(SHIFTR({a},{b}),{lsb},{width}) -> SEL({a},{lsb+b},{width})
1328 AstShiftR* const shiftp = VN_CAST(nodep->fromp(), ShiftR);
1329 if (!(m_doV && shiftp && VN_IS(shiftp->rhsp(), Const) && VN_IS(nodep->lsbp(), Const)
1330 && VN_IS(nodep->widthp(), Const))) {
1331 return false;
1332 }
1333 AstNodeExpr* const ap = shiftp->lhsp();
1334 AstConst* const bp = VN_AS(shiftp->rhsp(), Const);
1335 AstConst* const lp = VN_AS(nodep->lsbp(), Const);
1336 if (bp->isWide() || bp->num().isFourState() || bp->num().isNegative() || lp->isWide()
1337 || lp->num().isFourState() || lp->num().isNegative()) {
1338 return false;
1339 }
1340 const int newLsb = lp->toSInt() + bp->toSInt();
1341 if (newLsb + nodep->widthConst() > ap->width()) return false;
1342 //
1343 UINFO(9, "SEL(SHIFTR(a,b),l,w) -> SEL(a,l+b,w)\n");
1344 if (debug() >= 9) nodep->dumpTree("- SEL(SH)-in: ");
1345 AstSel* const newp
1346 = new AstSel{nodep->fileline(), ap->unlinkFrBack(), newLsb, nodep->widthConst()};
1347 newp->dtypeFrom(nodep);
1348 if (debug() >= 9) newp->dumpTree("- SEL(SH)-ou: ");
1349 nodep->replaceWith(newp);
1350 VL_DO_DANGLING(pushDeletep(nodep), nodep);
1351 return true;
1352 }
1353
1354 bool operandBiExtendConstShrink(AstNodeBiop* nodep) {
1355 // Loop unrolling favors standalone compares
1356 // EQ(const{width32}, EXTEND(xx{width3})) -> EQ(const{3}, xx{3})
1357 // The constant must have zero bits (+ 1 if signed) or compare
1358 // would be incorrect. See also operandBiExtendConst
1359 AstExtend* const extendp = VN_CAST(nodep->rhsp(), Extend);
1360 if (!extendp) return false;
1361 AstNodeExpr* const smallerp = extendp->lhsp();
1362 const int subsize = smallerp->width();
1363 AstConst* const constp = VN_CAST(nodep->lhsp(), Const);
1364 if (!constp) return false;
1365 if (!constp->num().isBitsZero(constp->width() - 1, subsize)) return false;
1366 //
1367 if (debug() >= 9) nodep->dumpTree("- BI(EXTEND)-in: ");
1368 smallerp->unlinkFrBack();
1369 VL_DO_DANGLING(pushDeletep(extendp->unlinkFrBack()), extendp); // aka nodep->lhsp.
1370 nodep->rhsp(smallerp);
1371
1372 constp->unlinkFrBack();
1373 V3Number num{constp, subsize};
1374 num.opAssign(constp->num());
1375 nodep->lhsp(new AstConst{constp->fileline(), num});
1376 VL_DO_DANGLING(pushDeletep(constp), constp);
1377 if (debug() >= 9) nodep->dumpTree("- BI(EXTEND)-ou: ");
1378 return true;
1379 }
1380 bool operandBiExtendConstOver(const AstNodeBiop* nodep) {
1381 // EQ(const{width32}, EXTEND(xx{width3})) -> constant
1382 // When the constant has non-zero bits above the extend it's a constant.
1383 // Avoids compiler warning
1384 const AstExtend* const extendp = VN_CAST(nodep->rhsp(), Extend);
1385 if (!extendp) return false;
1386 AstNode* const smallerp = extendp->lhsp();
1387 const int subsize = smallerp->width();
1388 const AstConst* const constp = VN_CAST(nodep->lhsp(), Const);
1389 if (!constp) return false;
1390 if (constp->num().isBitsZero(constp->width() - 1, subsize)) return false;
1391 return true;
1392 }
1393
1394 // Extraction checks
1395 bool warnSelect(AstSel* nodep) {
1396 if (m_doGenerate) {
1397 // Never checked yet
1398 V3Width::widthParamsEdit(nodep);
1399 iterateChildren(nodep); // May need "constifying"
1400 }
1401 // Find range of dtype we are selecting from
1402 // Similar code in V3Unknown::AstSel
1403 const bool doit = true;
1404 if (m_warn && VN_IS(nodep->lsbp(), Const) && VN_IS(nodep->widthp(), Const) && doit) {
1405 const int maxDeclBit = nodep->declRange().hiMaxSelect() * nodep->declElWidth()
1406 + (nodep->declElWidth() - 1);
1407 if (VN_AS(nodep->lsbp(), Const)->num().isFourState()
1408 || VN_AS(nodep->widthp(), Const)->num().isFourState()) {
1409 nodep->v3error("Selection index is constantly unknown or tristated: "
1410 "lsb="
1411 << nodep->lsbp()->name() << " width=" << nodep->widthp()->name());
1412 // Replacing nodep will make a mess above, so we replace the offender
1413 replaceZero(nodep->lsbp());
1414 } else if (nodep->declRange().ranged()
1415 && (nodep->msbConst() > maxDeclBit || nodep->lsbConst() > maxDeclBit)) {
1416 // See also warning in V3Width
1417 // Must adjust by element width as declRange() is in number of elements
1418 string msbLsbProtected;
1419 if (nodep->declElWidth() == 0) {
1420 msbLsbProtected = "(nodep->declElWidth() == 0) "
1421 + std::to_string(nodep->msbConst()) + ":"
1422 + std::to_string(nodep->lsbConst());
1423 } else {
1424 msbLsbProtected = std::to_string(nodep->msbConst() / nodep->declElWidth())
1425 + ":"
1426 + std::to_string(nodep->lsbConst() / nodep->declElWidth());
1427 }
1428 nodep->v3warn(SELRANGE,
1429 "Selection index out of range: "
1430 << msbLsbProtected << " outside "
1431 << nodep->declRange().hiMaxSelect() << ":0"
1432 << (nodep->declRange().lo() >= 0
1433 ? ""
1434 : (" (adjusted +" + cvtToStr(-nodep->declRange().lo())
1435 + " to account for negative lsb)")));
1436 UINFO(1, " Related Raw index is " << nodep->msbConst() << ":"
1437 << nodep->lsbConst() << endl);
1438 // Don't replace with zero, we'll do it later
1439 }
1440 }
1441 return false; // Not a transform, so NOP
1442 }
1443
1444 static bool operandsSame(AstNode* node1p, AstNode* node2p) {
1445 // For now we just detect constants & simple vars, though it could be more generic
1446 if (VN_IS(node1p, Const) && VN_IS(node2p, Const)) return node1p->sameGateTree(node2p);
1447 if (VN_IS(node1p, VarRef) && VN_IS(node2p, VarRef)) {
1448 // Avoid comparing widthMin's, which results in lost optimization attempts
1449 // If cleanup sameGateTree to be smarter, this can be restored.
1450 // return node1p->sameGateTree(node2p);
1451 return node1p->isSame(node2p);
1452 }
1453 // Pattern created by coverage-line; avoid compiler tautological-compare warning
1454 if (AstAnd* const and1p = VN_CAST(node1p, And)) {
1455 if (AstAnd* const and2p = VN_CAST(node2p, And)) {
1456 if (VN_IS(and1p->lhsp(), Const) && VN_IS(and1p->rhsp(), NodeVarRef)
1457 && VN_IS(and2p->lhsp(), Const) && VN_IS(and2p->rhsp(), NodeVarRef))
1458 return node1p->sameGateTree(node2p);
1459 }
1460 }
1461 return false;
1462 }
1463 bool ifSameAssign(const AstNodeIf* nodep) {
1464 const AstNodeAssign* const thensp = VN_CAST(nodep->thensp(), NodeAssign);
1465 const AstNodeAssign* const elsesp = VN_CAST(nodep->elsesp(), NodeAssign);
1466 if (!thensp || thensp->nextp()) return false; // Must be SINGLE statement
1467 if (!elsesp || elsesp->nextp()) return false;
1468 if (thensp->type() != elsesp->type()) return false; // Can't mix an assigndly with assign
1469 if (!thensp->lhsp()->sameGateTree(elsesp->lhsp())) return false;
1470 if (!thensp->rhsp()->gateTree()) return false;
1471 if (!elsesp->rhsp()->gateTree()) return false;
1472 if (m_underRecFunc) return false; // This optimization may lead to infinite recursion
1473 return true;
1474 }
1475 bool operandIfIf(const AstNodeIf* nodep) {
1476 if (nodep->elsesp()) return false;
1477 const AstNodeIf* const lowerIfp = VN_CAST(nodep->thensp(), NodeIf);
1478 if (!lowerIfp || lowerIfp->nextp()) return false;
1479 if (nodep->type() != lowerIfp->type()) return false;
1480 if (AstNode::afterCommentp(lowerIfp->elsesp())) return false;
1481 return true;
1482 }
1483 bool ifConcatMergeableBiop(const AstNode* nodep) {
1484 return (VN_IS(nodep, And) || VN_IS(nodep, Or) || VN_IS(nodep, Xor));
1485 }
1486 bool ifAdjacentSel(const AstSel* lhsp, const AstSel* rhsp) {
1487 if (!v3Global.opt.fAssemble()) return false; // opt disabled
1488 if (!lhsp || !rhsp) return false;
1489 const AstNode* const lfromp = lhsp->fromp();
1490 const AstNode* const rfromp = rhsp->fromp();
1491 if (!lfromp || !rfromp || !lfromp->sameGateTree(rfromp)) return false;
1492 const AstConst* const lstart = VN_CAST(lhsp->lsbp(), Const);
1493 const AstConst* const rstart = VN_CAST(rhsp->lsbp(), Const);
1494 const AstConst* const lwidth = VN_CAST(lhsp->widthp(), Const);
1495 const AstConst* const rwidth = VN_CAST(rhsp->widthp(), Const);
1496 if (!lstart || !rstart || !lwidth || !rwidth) return false; // too complicated
1497 const int rend = (rstart->toSInt() + rwidth->toSInt());
1498 return (rend == lstart->toSInt());
1499 }
1500 bool ifMergeAdjacent(AstNodeExpr* lhsp, AstNodeExpr* rhsp) {
1501 // called by concatmergeable to determine if {lhsp, rhsp} make sense
1502 if (!v3Global.opt.fAssemble()) return false; // opt disabled
1503 // two same varref
1504 if (operandsSame(lhsp, rhsp)) return true;
1505 const AstSel* lselp = VN_CAST(lhsp, Sel);
1506 const AstSel* rselp = VN_CAST(rhsp, Sel);
1507 // a[i:0] a
1508 if (lselp && !rselp && rhsp->sameGateTree(lselp->fromp()))
1509 rselp = new AstSel{rhsp->fileline(), rhsp->cloneTreePure(false), 0, rhsp->width()};
1510 // a[i:j] {a[j-1:k], b}
1511 if (lselp && !rselp && VN_IS(rhsp, Concat))
1512 return ifMergeAdjacent(lhsp, VN_CAST(rhsp, Concat)->lhsp());
1513 // a a[msb:j]
1514 if (rselp && !lselp && lhsp->sameGateTree(rselp->fromp()))
1515 lselp = new AstSel{lhsp->fileline(), lhsp->cloneTreePure(false), 0, lhsp->width()};
1516 // {b, a[j:k]} a[k-1:i]
1517 if (rselp && !lselp && VN_IS(lhsp, Concat))
1518 return ifMergeAdjacent(VN_CAST(lhsp, Concat)->rhsp(), rhsp);
1519 if (!lselp || !rselp) return false;
1520
1521 // a[a:b] a[b-1:c] are adjacent
1522 AstNode* const lfromp = lselp->fromp();
1523 AstNode* const rfromp = rselp->fromp();
1524 if (!lfromp || !rfromp || !lfromp->sameGateTree(rfromp)) return false;
1525 AstConst* const lstart = VN_CAST(lselp->lsbp(), Const);
1526 AstConst* const rstart = VN_CAST(rselp->lsbp(), Const);
1527 AstConst* const lwidth = VN_CAST(lselp->widthp(), Const);
1528 AstConst* const rwidth = VN_CAST(rselp->widthp(), Const);
1529 if (!lstart || !rstart || !lwidth || !rwidth) return false; // too complicated
1530 const int rend = (rstart->toSInt() + rwidth->toSInt());
1531 // a[i:j] a[j-1:k]
1532 if (rend == lstart->toSInt()) return true;
1533 // a[i:0] a[msb:j]
1534 if (rend == rfromp->width() && lstart->toSInt() == 0) return true;
1535 return false;
1536 }
1537 bool concatMergeable(const AstNodeExpr* lhsp, const AstNodeExpr* rhsp, unsigned depth) {
1538 // determine if {a OP b, c OP d} => {a, c} OP {b, d} is advantageous
1539 if (!v3Global.opt.fAssemble()) return false; // opt disabled
1540 if (lhsp->type() != rhsp->type()) return false;
1541 if (!ifConcatMergeableBiop(lhsp)) return false;
1542 if (depth > CONCAT_MERGABLE_MAX_DEPTH) return false; // As worse case O(n^2) algorithm
1543
1544 const AstNodeBiop* const lp = VN_CAST(lhsp, NodeBiop);
1545 const AstNodeBiop* const rp = VN_CAST(rhsp, NodeBiop);
1546 if (!lp || !rp) return false;
1547 // {a[]&b[], a[]&b[]}
1548 const bool lad = ifMergeAdjacent(lp->lhsp(), rp->lhsp());
1549 const bool rad = ifMergeAdjacent(lp->rhsp(), rp->rhsp());
1550 if (lad && rad) return true;
1551 // {a[] & b[]&c[], a[] & b[]&c[]}
1552 if (lad && concatMergeable(lp->rhsp(), rp->rhsp(), depth + 1)) return true;
1553 // {a[]&b[] & c[], a[]&b[] & c[]}
1554 if (rad && concatMergeable(lp->lhsp(), rp->lhsp(), depth + 1)) return true;
1555 // {(a[]&b[])&(c[]&d[]), (a[]&b[])&(c[]&d[])}
1556 if (concatMergeable(lp->lhsp(), rp->lhsp(), depth + 1)
1557 && concatMergeable(lp->rhsp(), rp->rhsp(), depth + 1)) {
1558 return true;
1559 }
1560 return false;
1561 }
1562 static bool operandsSameWidth(const AstNode* lhsp, const AstNode* rhsp) {
1563 return lhsp->width() == rhsp->width();
1564 }
1565
1566 //----------------------------------------
1567 // Constant Replacement functions.
1568 // These all take a node, delete its tree, and replaces it with a constant
1569
1570 void replaceNum(AstNode* oldp, const V3Number& num) {
1571 // Replace oldp node with a constant set to specified value
1572 UASSERT(oldp, "Null old");
1573 UASSERT_OBJ(!(VN_IS(oldp, Const) && !VN_AS(oldp, Const)->num().isFourState()), oldp,
1574 "Already constant??");
1575 AstNode* const newp = new AstConst{oldp->fileline(), num};
1576 newp->dtypeFrom(oldp);
1577 if (debug() > 5) oldp->dumpTree("- const_old: ");
1578 if (debug() > 5) newp->dumpTree("- _new: ");
1579 oldp->replaceWith(newp);
1580 VL_DO_DANGLING(pushDeletep(oldp), oldp);
1581 }
1582 void replaceNum(AstNode* nodep, uint32_t val) {
1583 V3Number num{nodep, nodep->width(), val};
1584 VL_DO_DANGLING(replaceNum(nodep, num), nodep);
1585 }
1586 void replaceNumSigned(AstNodeBiop* nodep, uint32_t val) {
1587 // We allow both sides to be constant, as one may have come from
1588 // parameter propagation, etc.
1589 if (m_warn && !(VN_IS(nodep->lhsp(), Const) && VN_IS(nodep->rhsp(), Const))) {
1590 nodep->v3warn(UNSIGNED, "Comparison is constant due to unsigned arithmetic");
1591 }
1592 VL_DO_DANGLING(replaceNum(nodep, val), nodep);
1593 }
1594 void replaceNumLimited(AstNodeBiop* nodep, uint32_t val) {
1595 // Avoids gcc warning about same
1596 if (m_warn) nodep->v3warn(CMPCONST, "Comparison is constant due to limited range");
1597 VL_DO_DANGLING(replaceNum(nodep, val), nodep);
1598 }
1599 void replaceZero(AstNode* nodep) { VL_DO_DANGLING(replaceNum(nodep, 0), nodep); }
1600 void replaceZeroChkPure(AstNode* nodep, AstNodeExpr* checkp) {
1601 // For example, "0 * n" -> 0 if n has no side effects
1602 // Else strength reduce it to 0 & n.
1603 // If ever change the operation note AstAnd rule specially ignores this created pattern
1604 if (checkp->isPure()) {
1605 VL_DO_DANGLING(replaceNum(nodep, 0), nodep);
1606 } else {
1607 AstNode* const newp = new AstAnd{nodep->fileline(), new AstConst{nodep->fileline(), 0},
1608 checkp->unlinkFrBack()};
1609 newp->dtypeFrom(nodep);
1610 nodep->replaceWith(newp);
1611 VL_DO_DANGLING(pushDeletep(nodep), nodep);
1612 }
1613 }
1614 void replaceAllOnes(AstNode* nodep) {
1615 V3Number ones{nodep, nodep->width(), 0};
1616 ones.setMask(nodep->width());
1617 VL_DO_DANGLING(replaceNum(nodep, ones), nodep);
1618 }
1619 void replaceConst(AstNodeUniop* nodep) {
1620 V3Number num{nodep, nodep->width()};
1621 nodep->numberOperate(num, VN_AS(nodep->lhsp(), Const)->num());
1622 UINFO(4, "UNICONST -> " << num << endl);
1623 VL_DO_DANGLING(replaceNum(nodep, num), nodep);
1624 }
1625 void replaceConst(AstNodeBiop* nodep) {
1626 V3Number num{nodep, nodep->width()};
1627 nodep->numberOperate(num, VN_AS(nodep->lhsp(), Const)->num(),
1628 VN_AS(nodep->rhsp(), Const)->num());
1629 UINFO(4, "BICONST -> " << num << endl);
1630 VL_DO_DANGLING(replaceNum(nodep, num), nodep);
1631 }
1632 void replaceConst(AstNodeTriop* nodep) {
1633 V3Number num{nodep, nodep->width()};
1634 nodep->numberOperate(num, VN_AS(nodep->lhsp(), Const)->num(),
1635 VN_AS(nodep->rhsp(), Const)->num(),
1636 VN_AS(nodep->thsp(), Const)->num());
1637 UINFO(4, "TRICONST -> " << num << endl);
1638 VL_DO_DANGLING(replaceNum(nodep, num), nodep);
1639 }
1640 void replaceConst(AstNodeQuadop* nodep) {
1641 V3Number num{nodep, nodep->width()};
1642 nodep->numberOperate(
1643 num, VN_AS(nodep->lhsp(), Const)->num(), VN_AS(nodep->rhsp(), Const)->num(),
1644 VN_AS(nodep->thsp(), Const)->num(), VN_AS(nodep->fhsp(), Const)->num());
1645 UINFO(4, "QUADCONST -> " << num << endl);
1646 VL_DO_DANGLING(replaceNum(nodep, num), nodep);
1647 }
1648
1649 void replaceConstString(AstNode* oldp, const string& num) {
1650 // Replace oldp node with a constant set to specified value
1651 UASSERT(oldp, "Null old");
1652 AstNode* const newp = new AstConst{oldp->fileline(), AstConst::String{}, num};
1653 if (debug() > 5) oldp->dumpTree("- const_old: ");
1654 if (debug() > 5) newp->dumpTree("- _new: ");
1655 oldp->replaceWith(newp);
1656 VL_DO_DANGLING(pushDeletep(oldp), oldp);
1657 }
1658 //----------------------------------------
1659 // Replacement functions.
1660 // These all take a node and replace it with something else
1661
1662 void replaceWChild(AstNode* nodep, AstNodeExpr* childp) {
1663 // NODE(..., CHILD(...)) -> CHILD(...)
1664 childp->unlinkFrBackWithNext();
1665 // If replacing a SEL for example, the data type comes from the parent (is less wide).
1666 // This may adversely affect the operation of the node being replaced.
1667 childp->dtypeFrom(nodep);
1668 nodep->replaceWith(childp);
1669 VL_DO_DANGLING(pushDeletep(nodep), nodep);
1670 }
1671 void replaceWChildBool(AstNode* nodep, AstNodeExpr* childp) {
1672 // NODE(..., CHILD(...)) -> REDOR(CHILD(...))
1673 childp->unlinkFrBack();
1674 if (childp->width1()) {
1675 nodep->replaceWith(childp);
1676 } else {
1677 nodep->replaceWith(new AstRedOr{childp->fileline(), childp});
1678 }
1679 VL_DO_DANGLING(pushDeletep(nodep), nodep);
1680 }
1681
1682 //! Replace a ternary node with its RHS after iterating
1683 //! Used with short-circuiting, where the RHS has not yet been iterated.
1684 void replaceWIteratedRhs(AstNodeTriop* nodep) {
1685 if (AstNode* const rhsp = nodep->rhsp()) iterateAndNextNull(rhsp);
1686 replaceWChild(nodep, nodep->rhsp()); // May have changed
1687 }
1688
1689 //! Replace a ternary node with its THS after iterating
1690 //! Used with short-circuiting, where the THS has not yet been iterated.
1691 void replaceWIteratedThs(AstNodeTriop* nodep) {
1692 if (AstNode* const thsp = nodep->thsp()) iterateAndNextNull(thsp);
1693 replaceWChild(nodep, nodep->thsp()); // May have changed
1694 }
1695 void replaceWLhs(AstNodeUniop* nodep) {
1696 // Keep LHS, remove RHS
1697 replaceWChild(nodep, nodep->lhsp());
1698 }
1699 void replaceWLhs(AstNodeBiop* nodep) {
1700 // Keep LHS, remove RHS
1701 replaceWChild(nodep, nodep->lhsp());
1702 }
1703 void replaceWRhs(AstNodeBiop* nodep) {
1704 // Keep RHS, remove LHS
1705 replaceWChild(nodep, nodep->rhsp());
1706 }
1707 void replaceWLhsBool(AstNodeBiop* nodep) { replaceWChildBool(nodep, nodep->lhsp()); }
1708 void replaceWRhsBool(AstNodeBiop* nodep) { replaceWChildBool(nodep, nodep->rhsp()); }
1709 void replaceAsv(AstNodeBiop* nodep) {
1710 // BIASV(CONSTa, BIASV(CONSTb, c)) -> BIASV( BIASV_CONSTED(a,b), c)
1711 // BIASV(SAMEa, BIASV(SAMEb, c)) -> BIASV( BIASV(SAMEa,SAMEb), c)
1712 // nodep->dumpTree("- repAsvConst_old: ");
1713 AstNodeExpr* const ap = nodep->lhsp();
1714 AstNodeBiop* const rp = VN_AS(nodep->rhsp(), NodeBiop);
1715 AstNodeExpr* const bp = rp->lhsp();
1716 AstNodeExpr* const cp = rp->rhsp();
1717 ap->unlinkFrBack();
1718 bp->unlinkFrBack();
1719 cp->unlinkFrBack();
1720 rp->unlinkFrBack();
1721 nodep->lhsp(rp);
1722 nodep->rhsp(cp);
1723 rp->lhsp(ap);
1724 rp->rhsp(bp);
1725 if (VN_IS(rp->lhsp(), Const) && VN_IS(rp->rhsp(), Const)) replaceConst(rp);
1726 // nodep->dumpTree("- repAsvConst_new: ");
1727 }
1728 void replaceAsvLUp(AstNodeBiop* nodep) {
1729 // BIASV(BIASV(CONSTll,lr),r) -> BIASV(CONSTll,BIASV(lr,r))
1730 AstNodeBiop* const lp = VN_AS(nodep->lhsp()->unlinkFrBack(), NodeBiop);
1731 AstNodeExpr* const llp = lp->lhsp()->unlinkFrBack();
1732 AstNodeExpr* const lrp = lp->rhsp()->unlinkFrBack();
1733 AstNodeExpr* const rp = nodep->rhsp()->unlinkFrBack();
1734 nodep->lhsp(llp);
1735 nodep->rhsp(lp);
1736 lp->lhsp(lrp);
1737 lp->rhsp(rp);
1738 // nodep->dumpTree("- repAsvLUp_new: ");
1739 }
1740 void replaceAsvRUp(AstNodeBiop* nodep) {
1741 // BIASV(l,BIASV(CONSTrl,rr)) -> BIASV(CONSTrl,BIASV(l,rr))
1742 AstNodeExpr* const lp = nodep->lhsp()->unlinkFrBack();
1743 AstNodeBiop* const rp = VN_AS(nodep->rhsp()->unlinkFrBack(), NodeBiop);
1744 AstNodeExpr* const rlp = rp->lhsp()->unlinkFrBack();
1745 AstNodeExpr* const rrp = rp->rhsp()->unlinkFrBack();
1746 nodep->lhsp(rlp);
1747 nodep->rhsp(rp);
1748 rp->lhsp(lp);
1749 rp->rhsp(rrp);
1750 // nodep->dumpTree("- repAsvRUp_new: ");
1751 }
1752 void replaceAndOr(AstNodeBiop* nodep) {
1753 // OR (AND (CONSTll,lr), AND(CONSTrl==ll,rr)) -> AND (CONSTll, OR(lr,rr))
1754 // OR (AND (CONSTll,lr), AND(CONSTrl, rr=lr)) -> AND (OR(ll,rl), rr)
1755 // nodep ^lp ^llp ^lrp ^rp ^rlp ^rrp
1756 // (Or/And may also be reversed)
1757 AstNodeBiop* const lp = VN_AS(nodep->lhsp()->unlinkFrBack(), NodeBiop);
1758 AstNodeExpr* const llp = lp->lhsp()->unlinkFrBack();
1759 AstNodeExpr* const lrp = lp->rhsp()->unlinkFrBack();
1760 AstNodeBiop* const rp = VN_AS(nodep->rhsp()->unlinkFrBack(), NodeBiop);
1761 AstNodeExpr* const rlp = rp->lhsp()->unlinkFrBack();
1762 AstNodeExpr* const rrp = rp->rhsp()->unlinkFrBack();
1763 nodep->replaceWith(lp);
1764 if (operandsSame(llp, rlp)) {
1765 lp->lhsp(llp);
1766 lp->rhsp(nodep);
1767 lp->dtypeFrom(nodep);
1768 nodep->lhsp(lrp);
1769 nodep->rhsp(rrp);
1770 VL_DO_DANGLING(pushDeletep(rp), rp);
1771 VL_DO_DANGLING(pushDeletep(rlp), rlp);
1772 } else if (operandsSame(lrp, rrp)) {
1773 lp->lhsp(nodep);
1774 lp->rhsp(rrp);
1775 lp->dtypeFrom(nodep);
1776 nodep->lhsp(llp);
1777 nodep->rhsp(rlp);
1778 VL_DO_DANGLING(pushDeletep(rp), rp);
1779 VL_DO_DANGLING(pushDeletep(lrp), lrp);
1780 } else {
1781 nodep->v3fatalSrc("replaceAndOr on something operandAndOrSame shouldn't have matched");
1782 }
1783 // nodep->dumpTree("- repAndOr_new: ");
1784 }
1785 void replaceShiftSame(AstNodeBiop* nodep) {
1786 // Or(Shift(ll,CONSTlr),Shift(rl,CONSTrr==lr)) -> Shift(Or(ll,rl),CONSTlr)
1787 // (Or/And may also be reversed)
1788 AstNodeBiop* const lp = VN_AS(nodep->lhsp()->unlinkFrBack(), NodeBiop);
1789 AstNodeExpr* const llp = lp->lhsp()->unlinkFrBack();
1790 AstNodeExpr* const lrp = lp->rhsp()->unlinkFrBack();
1791 AstNodeBiop* const rp = VN_AS(nodep->rhsp()->unlinkFrBack(), NodeBiop);
1792 AstNodeExpr* const rlp = rp->lhsp()->unlinkFrBack();
1793 AstNodeExpr* const rrp = rp->rhsp()->unlinkFrBack();
1794 nodep->replaceWith(lp);
1795 lp->lhsp(nodep);
1796 lp->rhsp(lrp);
1797 nodep->lhsp(llp);
1798 nodep->rhsp(rlp);
1799 nodep->dtypep(llp->dtypep()); // dtype of Biop is before shift.
1800 VL_DO_DANGLING(pushDeletep(rp), rp);
1801 VL_DO_DANGLING(pushDeletep(rrp), rrp);
1802 // nodep->dumpTree("- repShiftSame_new: ");
1803 }
1804 void replaceConcatSel(AstConcat* nodep) {
1805 // {a[1], a[0]} -> a[1:0]
1806 AstSel* const lselp = VN_AS(nodep->lhsp()->unlinkFrBack(), Sel);
1807 AstSel* const rselp = VN_AS(nodep->rhsp()->unlinkFrBack(), Sel);
1808 const int lstart = lselp->lsbConst();
1809 const int lwidth = lselp->widthConst();
1810 const int rstart = rselp->lsbConst();
1811 const int rwidth = rselp->widthConst();
1812
1813 UASSERT_OBJ((rstart + rwidth) == lstart, nodep,
1814 "tried to merge two selects which are not adjacent");
1815 AstSel* const newselp = new AstSel{
1816 lselp->fromp()->fileline(), rselp->fromp()->unlinkFrBack(), rstart, lwidth + rwidth};
1817 UINFO(5, "merged two adjacent sel " << lselp << " and " << rselp << " to one " << newselp
1818 << endl);
1819
1820 nodep->replaceWith(newselp);
1821 VL_DO_DANGLING(pushDeletep(lselp), lselp);
1822 VL_DO_DANGLING(pushDeletep(rselp), rselp);
1823 VL_DO_DANGLING(pushDeletep(nodep), nodep);
1824 }
1825 void replaceConcatMerge(AstConcat* nodep) {
1826 // {llp OP lrp, rlp OP rrp} => {llp, rlp} OP {lrp, rrp}, where OP = AND/OR/XOR
1827 AstNodeBiop* const lp = VN_AS(nodep->lhsp(), NodeBiop);
1828 AstNodeBiop* const rp = VN_AS(nodep->rhsp(), NodeBiop);
1829 if (concatMergeable(lp, rp, 0)) {
1830 AstNodeExpr* const llp = lp->lhsp();
1831 AstNodeExpr* const lrp = lp->rhsp();
1832 AstNodeExpr* const rlp = rp->lhsp();
1833 AstNodeExpr* const rrp = rp->rhsp();
1834 AstConcat* const newlp = new AstConcat{rlp->fileline(), llp->cloneTreePure(false),
1835 rlp->cloneTreePure(false)};
1836 AstConcat* const newrp = new AstConcat{rrp->fileline(), lrp->cloneTreePure(false),
1837 rrp->cloneTreePure(false)};
1838 // use the lhs to replace the parent concat
1839 llp->replaceWith(newlp);
1840 VL_DO_DANGLING(pushDeletep(llp), llp);
1841 lrp->replaceWith(newrp);
1842 VL_DO_DANGLING(pushDeletep(lrp), lrp);
1843 lp->dtypeChgWidthSigned(newlp->width(), newlp->width(), VSigning::UNSIGNED);
1844 UINFO(5, "merged " << nodep << endl);
1845 VL_DO_DANGLING(pushDeletep(rp->unlinkFrBack()), rp);
1846 nodep->replaceWith(lp->unlinkFrBack());
1847 VL_DO_DANGLING(pushDeletep(nodep), nodep);
1848 iterate(lp->lhsp());
1849 iterate(lp->rhsp());
1850 } else {
1851 nodep->v3fatalSrc("tried to merge two Concat which are not adjacent");
1852 }
1853 }
1854 void replaceExtend(AstNode* nodep, AstNodeExpr* arg0p) {
1855 // -> EXTEND(nodep)
1856 // like a AstExtend{$rhsp}, but we need to set the width correctly from base node
1857 arg0p->unlinkFrBack();
1858 AstNodeExpr* const newp
1859 = (VN_IS(nodep, ExtendS)
1860 ? static_cast<AstNodeExpr*>(new AstExtendS{nodep->fileline(), arg0p})
1861 : static_cast<AstNodeExpr*>(new AstExtend{nodep->fileline(), arg0p}));
1862 newp->dtypeFrom(nodep);
1863 nodep->replaceWith(newp);
1864 VL_DO_DANGLING(pushDeletep(nodep), nodep);
1865 }
1866 void replacePowShift(AstNodeBiop* nodep) { // Pow or PowS
1867 UINFO(5, "POW(2,b)->SHIFTL(1,b) " << nodep << endl);
1868 AstNodeExpr* const rhsp = nodep->rhsp()->unlinkFrBack();
1869 AstShiftL* const newp
1870 = new AstShiftL{nodep->fileline(), new AstConst{nodep->fileline(), 1}, rhsp};
1871 newp->dtypeFrom(nodep);
1872 newp->lhsp()->dtypeFrom(nodep);
1873 nodep->replaceWith(newp);
1874 VL_DO_DANGLING(pushDeletep(nodep), nodep);
1875 }
1876 void replaceMulShift(AstMul* nodep) { // Mul, but not MulS as not simple shift
1877 UINFO(5, "MUL(2^n,b)->SHIFTL(b,n) " << nodep << endl);
1878 const int amount = VN_AS(nodep->lhsp(), Const)->num().mostSetBitP1() - 1; // 2^n->n+1
1879 AstNodeExpr* const opp = nodep->rhsp()->unlinkFrBack();
1880 AstShiftL* const newp
1881 = new AstShiftL{nodep->fileline(), opp, new AstConst(nodep->fileline(), amount)};
1882 newp->dtypeFrom(nodep);
1883 nodep->replaceWith(newp);
1884 VL_DO_DANGLING(pushDeletep(nodep), nodep);
1885 }
1886 void replaceDivShift(AstDiv* nodep) { // Mul, but not MulS as not simple shift
1887 UINFO(5, "DIV(b,2^n)->SHIFTR(b,n) " << nodep << endl);
1888 const int amount = VN_AS(nodep->rhsp(), Const)->num().mostSetBitP1() - 1; // 2^n->n+1
1889 AstNodeExpr* const opp = nodep->lhsp()->unlinkFrBack();
1890 AstShiftR* const newp
1891 = new AstShiftR{nodep->fileline(), opp, new AstConst(nodep->fileline(), amount)};
1892 newp->dtypeFrom(nodep);
1893 nodep->replaceWith(newp);
1894 VL_DO_DANGLING(pushDeletep(nodep), nodep);
1895 }
1896 void replaceModAnd(AstModDiv* nodep) { // Mod, but not ModS as not simple shift
1897 UINFO(5, "MOD(b,2^n)->AND(b,2^n-1) " << nodep << endl);
1898 const int amount = VN_AS(nodep->rhsp(), Const)->num().mostSetBitP1() - 1; // 2^n->n+1
1899 V3Number mask{nodep, nodep->width()};
1900 mask.setMask(amount);
1901 AstNodeExpr* const opp = nodep->lhsp()->unlinkFrBack();
1902 AstAnd* const newp
1903 = new AstAnd{nodep->fileline(), opp, new AstConst{nodep->fileline(), mask}};
1904 newp->dtypeFrom(nodep);
1905 nodep->replaceWith(newp);
1906 VL_DO_DANGLING(pushDeletep(nodep), nodep);
1907 }
1908 void replaceShiftOp(AstNodeBiop* nodep) {
1909 UINFO(5, "SHIFT(AND(a,b),CONST)->AND(SHIFT(a,CONST),SHIFT(b,CONST)) " << nodep << endl);
1910 const int width = nodep->width();
1911 const int widthMin = nodep->widthMin();
1912 VNRelinker handle;
1913 nodep->unlinkFrBack(&handle);
1914 AstNodeBiop* const lhsp = VN_AS(nodep->lhsp(), NodeBiop);
1915 lhsp->unlinkFrBack();
1916 AstNodeExpr* const shiftp = nodep->rhsp()->unlinkFrBack();
1917 AstNodeExpr* const ap = lhsp->lhsp()->unlinkFrBack();
1918 AstNodeExpr* const bp = lhsp->rhsp()->unlinkFrBack();
1919 AstNodeBiop* const shift1p = nodep;
1920 AstNodeBiop* const shift2p = nodep->cloneTree(true);
1921 shift1p->lhsp(ap);
1922 shift1p->rhsp(shiftp->cloneTreePure(true));
1923 shift2p->lhsp(bp);
1924 shift2p->rhsp(shiftp);
1925 AstNodeBiop* const newp = lhsp;
1926 newp->lhsp(shift1p);
1927 newp->rhsp(shift2p);
1928 newp->dtypeChgWidth(width, widthMin); // The new AND must have width of the original SHIFT
1929 handle.relink(newp);
1930 iterate(newp); // Further reduce, either node may have more reductions.
1931 }
1932 void replaceShiftShift(AstNodeBiop* nodep) {
1933 UINFO(4, "SHIFT(SHIFT(a,s1),s2)->SHIFT(a,ADD(s1,s2)) " << nodep << endl);
1934 if (debug() >= 9) nodep->dumpTree("- repShiftShift_old: ");
1935 AstNodeBiop* const lhsp = VN_AS(nodep->lhsp(), NodeBiop);
1936 lhsp->unlinkFrBack();
1937 AstNodeExpr* const ap = lhsp->lhsp()->unlinkFrBack();
1938 AstNodeExpr* const shift1p = lhsp->rhsp()->unlinkFrBack();
1939 AstNodeExpr* const shift2p = nodep->rhsp()->unlinkFrBack();
1940 // Shift1p and shift2p may have different sizes, both are
1941 // self-determined so sum with infinite width
1942 if (nodep->type() == lhsp->type()) {
1943 const int shift1 = VN_AS(shift1p, Const)->toUInt();
1944 const int shift2 = VN_AS(shift2p, Const)->toUInt();
1945 const int newshift = shift1 + shift2;
1946 VL_DO_DANGLING(pushDeletep(shift1p), shift1p);
1947 VL_DO_DANGLING(pushDeletep(shift2p), shift2p);
1948 nodep->lhsp(ap);
1949 nodep->rhsp(new AstConst(nodep->fileline(), newshift));
1950 iterate(nodep); // Further reduce, either node may have more reductions.
1951 } else {
1952 // We know shift amounts are constant, but might be a mixed left/right shift
1953 int shift1 = VN_AS(shift1p, Const)->toUInt();
1954 if (VN_IS(lhsp, ShiftR)) shift1 = -shift1;
1955 int shift2 = VN_AS(shift2p, Const)->toUInt();
1956 if (VN_IS(nodep, ShiftR)) shift2 = -shift2;
1957 const int newshift = shift1 + shift2;
1958 VL_DO_DANGLING(pushDeletep(shift1p), shift1p);
1959 VL_DO_DANGLING(pushDeletep(shift2p), shift2p);
1960 AstNodeExpr* newp;
1961 V3Number mask1{nodep, nodep->width()};
1962 V3Number ones{nodep, nodep->width()};
1963 ones.setMask(nodep->width());
1964 if (shift1 < 0) {
1965 mask1.opShiftR(ones, V3Number(nodep, VL_IDATASIZE, -shift1));
1966 } else {
1967 mask1.opShiftL(ones, V3Number(nodep, VL_IDATASIZE, shift1));
1968 }
1969 V3Number mask{nodep, nodep->width()};
1970 if (shift2 < 0) {
1971 mask.opShiftR(mask1, V3Number(nodep, VL_IDATASIZE, -shift2));
1972 } else {
1973 mask.opShiftL(mask1, V3Number(nodep, VL_IDATASIZE, shift2));
1974 }
1975 if (newshift < 0) {
1976 newp = new AstShiftR{nodep->fileline(), ap,
1977 new AstConst(nodep->fileline(), -newshift)};
1978 } else {
1979 newp = new AstShiftL{nodep->fileline(), ap,
1980 new AstConst(nodep->fileline(), newshift)};
1981 }
1982 newp->dtypeFrom(nodep);
1983 newp = new AstAnd{nodep->fileline(), newp, new AstConst{nodep->fileline(), mask}};
1984 newp->dtypeFrom(nodep);
1985 nodep->replaceWith(newp);
1986 VL_DO_DANGLING(pushDeletep(nodep), nodep);
1987 // newp->dumpTree("- repShiftShift_new: ");
1988 iterate(newp); // Further reduce, either node may have more reductions.
1989 }
1990 VL_DO_DANGLING(pushDeletep(lhsp), lhsp);
1991 }
1992
1993 bool replaceAssignMultiSel(AstNodeAssign* nodep) {
1994 // Multiple assignments to sequential bits can be concated
1995 // ASSIGN(SEL(a),aq), ASSIGN(SEL(a+1),bq) -> ASSIGN(SEL(a:b),CONCAT(aq,bq)
1996 // ie. assign var[2]=a, assign var[3]=b -> assign var[3:2]={b,a}
1997
1998 // Skip if we're not const'ing an entire module (IE doing only one assign, etc)
1999 if (!m_modp) return false;
2000 AstSel* const sel1p = VN_CAST(nodep->lhsp(), Sel);
2001 if (!sel1p) return false;
2002 AstNodeAssign* const nextp = VN_CAST(nodep->nextp(), NodeAssign);
2003 if (!nextp) return false;
2004 if (nodep->type() != nextp->type()) return false;
2005 AstSel* const sel2p = VN_CAST(nextp->lhsp(), Sel);
2006 if (!sel2p) return false;
2007 AstVarRef* const varref1p = VN_CAST(sel1p->fromp(), VarRef);
2008 if (!varref1p) return false;
2009 AstVarRef* const varref2p = VN_CAST(sel2p->fromp(), VarRef);
2010 if (!varref2p) return false;
2011 if (!varref1p->sameGateTree(varref2p)) return false;
2012 AstConst* const con1p = VN_CAST(sel1p->lsbp(), Const);
2013 if (!con1p) return false;
2014 AstConst* const con2p = VN_CAST(sel2p->lsbp(), Const);
2015 if (!con2p) return false;
2016 // We need to make sure there's no self-references involved in either
2017 // assignment. For speed, we only look 3 deep, then give up.
2018 if (!varNotReferenced(nodep->rhsp(), varref1p->varp())) return false;
2019 if (!varNotReferenced(nextp->rhsp(), varref2p->varp())) return false;
2020 // If a variable is marked split_var, access to the variable should not be merged.
2021 if (varref1p->varp()->attrSplitVar() || varref2p->varp()->attrSplitVar()) return false;
2022 // Swap?
2023 if ((con1p->toSInt() != con2p->toSInt() + sel2p->width())
2024 && (con2p->toSInt() != con1p->toSInt() + sel1p->width())) {
2025 return false;
2026 }
2027 const bool lsbFirstAssign = (con1p->toUInt() < con2p->toUInt());
2028 UINFO(4, "replaceAssignMultiSel " << nodep << endl);
2029 UINFO(4, " && " << nextp << endl);
2030 // nodep->dumpTree("- comb1: ");
2031 // nextp->dumpTree("- comb2: ");
2032 AstNodeExpr* const rhs1p = nodep->rhsp()->unlinkFrBack();
2033 AstNodeExpr* const rhs2p = nextp->rhsp()->unlinkFrBack();
2034 AstNodeAssign* newp;
2035 if (lsbFirstAssign) {
2036 newp = nodep->cloneType(new AstSel{sel1p->fileline(), varref1p->unlinkFrBack(),
2037 sel1p->lsbConst(), sel1p->width() + sel2p->width()},
2038 new AstConcat{rhs1p->fileline(), rhs2p, rhs1p});
2039 } else {
2040 newp = nodep->cloneType(new AstSel{sel1p->fileline(), varref1p->unlinkFrBack(),
2041 sel2p->lsbConst(), sel1p->width() + sel2p->width()},
2042 new AstConcat{rhs1p->fileline(), rhs1p, rhs2p});
2043 }
2044 // pnewp->dumpTree("- conew: ");
2045 nodep->replaceWith(newp);
2046 VL_DO_DANGLING(pushDeletep(nodep), nodep);
2047 VL_DO_DANGLING(pushDeletep(nextp->unlinkFrBack()), nextp);
2048 return true;
2049 }
2050
2051 bool varNotReferenced(AstNode* nodep, AstVar* varp, int level = 0) {
2052 // Return true if varp never referenced under node.
2053 // Return false if referenced, or tree too deep to be worth it, or side effects
2054 if (!nodep) return true;
2055 if (level > 2) return false;
2056 if (!nodep->isPure()) return false; // For example a $fgetc can't be reordered
2057 if (VN_IS(nodep, NodeVarRef) && VN_AS(nodep, NodeVarRef)->varp() == varp) return false;
2058 return (varNotReferenced(nodep->nextp(), varp, level + 1)
2059 && varNotReferenced(nodep->op1p(), varp, level + 1)
2060 && varNotReferenced(nodep->op2p(), varp, level + 1)
2061 && varNotReferenced(nodep->op3p(), varp, level + 1)
2062 && varNotReferenced(nodep->op4p(), varp, level + 1));
2063 }
2064
2065 bool replaceNodeAssign(AstNodeAssign* nodep) {
2066 if (VN_IS(nodep->lhsp(), VarRef) && VN_IS(nodep->rhsp(), VarRef)
2067 && VN_AS(nodep->lhsp(), VarRef)->sameNoLvalue(VN_AS(nodep->rhsp(), VarRef))
2068 && !VN_IS(nodep, AssignDly)) {
2069 // X = X. Quite pointless, though X <= X may override another earlier assignment
2070 if (VN_IS(nodep, AssignW)) {
2071 nodep->v3error("Wire inputs its own output, creating circular logic (wire x=x)");
2072 return false; // Don't delete the assign, or V3Gate will freak out
2073 } else {
2074 VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep);
2075 return true;
2076 }
2077 } else if (m_doV && VN_IS(nodep->lhsp(), Concat) && nodep->isPure()) {
2078 bool need_temp = false;
2079 if (m_warn && !VN_IS(nodep, AssignDly)) { // Is same var on LHS and RHS?
2080 // Note only do this (need user4) when m_warn, which is
2081 // done as unique visitor
2082 const VNUser4InUse m_inuser4;
2083 nodep->lhsp()->foreach([](const AstVarRef* nodep) {
2084 if (nodep->varp()) nodep->varp()->user4(1);
2085 });
2086 nodep->rhsp()->foreach([&need_temp](const AstVarRef* nodep) {
2087 if (nodep->varp() && nodep->varp()->user4()) need_temp = true;
2088 });
2089 }
2090 if (need_temp) {
2091 // The first time we constify, there may be the same variable on the LHS
2092 // and RHS. In that case, we must use temporaries, or {a,b}={b,a} will break.
2093 UINFO(4, " ASSITEMP " << nodep << endl);
2094 // ASSIGN(CONCAT(lc1,lc2),rhs) -> ASSIGN(temp1,SEL(rhs,{size})),
2095 // ASSIGN(temp2,SEL(newrhs,{size}))
2096 // ASSIGN(lc1,temp1),
2097 // ASSIGN(lc2,temp2)
2098 } else {
2099 UINFO(4, " ASSI " << nodep << endl);
2100 // ASSIGN(CONCAT(lc1,lc2),rhs) -> ASSIGN(lc1,SEL(rhs,{size})),
2101 // ASSIGN(lc2,SEL(newrhs,{size}))
2102 }
2103 if (debug() >= 9) nodep->dumpTree("- Ass_old: ");
2104 // Unlink the stuff
2105 AstNodeExpr* const lc1p = VN_AS(nodep->lhsp(), Concat)->lhsp()->unlinkFrBack();
2106 AstNodeExpr* const lc2p = VN_AS(nodep->lhsp(), Concat)->rhsp()->unlinkFrBack();
2107 AstNodeExpr* const conp = VN_AS(nodep->lhsp(), Concat)->unlinkFrBack();
2108 AstNodeExpr* const rhsp = nodep->rhsp()->unlinkFrBack();
2109 AstNodeExpr* const rhs2p = rhsp->cloneTreePure(false);
2110 // Calc widths
2111 const int lsb2 = 0;
2112 const int msb2 = lsb2 + lc2p->width() - 1;
2113 const int lsb1 = msb2 + 1;
2114 const int msb1 = lsb1 + lc1p->width() - 1;
2115 UASSERT_OBJ(msb1 == (conp->width() - 1), nodep, "Width calc mismatch");
2116 // Form ranges
2117 AstSel* const sel1p = new AstSel{conp->fileline(), rhsp, lsb1, msb1 - lsb1 + 1};
2118 AstSel* const sel2p = new AstSel{conp->fileline(), rhs2p, lsb2, msb2 - lsb2 + 1};
2119 // Make new assigns of same flavor as old one
2120 //*** Not cloneTree; just one node.
2121 AstNodeAssign* newp = nullptr;
2122 if (!need_temp) {
2123 AstNodeAssign* const asn1ap = nodep->cloneType(lc1p, sel1p);
2124 AstNodeAssign* const asn2ap = nodep->cloneType(lc2p, sel2p);
2125 asn1ap->dtypeFrom(sel1p);
2126 asn2ap->dtypeFrom(sel2p);
2127 newp = AstNode::addNext(newp, asn1ap);
2128 newp = AstNode::addNext(newp, asn2ap);
2129 } else {
2130 UASSERT_OBJ(m_modp, nodep, "Not under module");
2131 UASSERT_OBJ(m_globalPass, nodep,
2132 "Should not reach here when not invoked on whole AstNetlist");
2133 // We could create just one temp variable, but we'll get better optimization
2134 // if we make one per term.
2135 AstVar* const temp1p
2136 = new AstVar{sel1p->fileline(), VVarType::BLOCKTEMP,
2137 m_concswapNames.get(sel1p), VFlagLogicPacked{}, msb1 - lsb1 + 1};
2138 AstVar* const temp2p
2139 = new AstVar{sel2p->fileline(), VVarType::BLOCKTEMP,
2140 m_concswapNames.get(sel2p), VFlagLogicPacked{}, msb2 - lsb2 + 1};
2141 m_modp->addStmtsp(temp1p);
2142 m_modp->addStmtsp(temp2p);
2143 AstNodeAssign* const asn1ap = nodep->cloneType(
2144 new AstVarRef{sel1p->fileline(), temp1p, VAccess::WRITE}, sel1p);
2145 AstNodeAssign* const asn2ap = nodep->cloneType(
2146 new AstVarRef{sel2p->fileline(), temp2p, VAccess::WRITE}, sel2p);
2147 AstNodeAssign* const asn1bp = nodep->cloneType(
2148 lc1p, new AstVarRef{sel1p->fileline(), temp1p, VAccess::READ});
2149 AstNodeAssign* const asn2bp = nodep->cloneType(
2150 lc2p, new AstVarRef{sel2p->fileline(), temp2p, VAccess::READ});
2151 asn1ap->dtypeFrom(temp1p);
2152 asn1bp->dtypeFrom(temp1p);
2153 asn2ap->dtypeFrom(temp2p);
2154 asn2bp->dtypeFrom(temp2p);
2155 // This order matters
2156 newp = AstNode::addNext(newp, asn1ap);
2157 newp = AstNode::addNext(newp, asn2ap);
2158 newp = AstNode::addNext(newp, asn1bp);
2159 newp = AstNode::addNext(newp, asn2bp);
2160 }
2161 if (debug() >= 9 && newp) newp->dumpTreeAndNext(cout, "- _new: ");
2162 nodep->addNextHere(newp);
2163 // Cleanup
2164 VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep);
2165 VL_DO_DANGLING(pushDeletep(conp), conp);
2166 // Further reduce, either node may have more reductions.
2167 return true;
2168 } else if (m_doV && VN_IS(nodep->rhsp(), StreamR)) {
2169 // The right-streaming operator on rhs of assignment does not
2170 // change the order of bits. Eliminate stream but keep its lhsp.
2171 // Add a cast if needed.
2172 AstStreamR* const streamp = VN_AS(nodep->rhsp(), StreamR)->unlinkFrBack();
2173 AstNodeExpr* srcp = streamp->lhsp()->unlinkFrBack();
2174 AstNodeDType* const srcDTypep = srcp->dtypep();
2175 if (VN_IS(srcDTypep, QueueDType) || VN_IS(srcDTypep, DynArrayDType)) {
2176 srcp = new AstCvtArrayToPacked{srcp->fileline(), srcp, nodep->dtypep()};
2177 } else if (VN_IS(srcDTypep, UnpackArrayDType)) {
2178 srcp = new AstCvtArrayToPacked{srcp->fileline(), srcp, srcDTypep};
2179 // Handling the case where lhs is wider than rhs by inserting zeros. StreamL does
2180 // not require this, since the left streaming operator implicitly handles this.
2181 const int packedBits = nodep->lhsp()->widthMin();
2182 const int unpackBits
2183 = srcDTypep->arrayUnpackedElements() * srcDTypep->subDTypep()->widthMin();
2184 const uint32_t offset = packedBits > unpackBits ? packedBits - unpackBits : 0;
2185 srcp = new AstShiftL{srcp->fileline(), srcp,
2186 new AstConst{srcp->fileline(), offset}, packedBits};
2187 }
2188 nodep->rhsp(srcp);
2189 VL_DO_DANGLING(pushDeletep(streamp), streamp);
2190 // Further reduce, any of the nodes may have more reductions.
2191 return true;
2192 } else if (m_doV && VN_IS(nodep->lhsp(), StreamL)) {
2193 // Push the stream operator to the rhs of the assignment statement
2194 AstNodeExpr* streamp = nodep->lhsp()->unlinkFrBack();
2195 AstNodeExpr* const dstp = VN_AS(streamp, StreamL)->lhsp()->unlinkFrBack();
2196 AstNodeExpr* const srcp = nodep->rhsp()->unlinkFrBack();
2197 const int sWidth = srcp->width();
2198 const int dWidth = dstp->width();
2199 // Connect the rhs to the stream operator and update its width
2200 VN_AS(streamp, StreamL)->lhsp(srcp);
2201 if (VN_IS(srcp->dtypep(), DynArrayDType) || VN_IS(srcp->dtypep(), QueueDType)
2202 || VN_IS(srcp->dtypep(), UnpackArrayDType)) {
2203 streamp->dtypeSetStream();
2204 } else {
2205 streamp->dtypeSetLogicUnsized(srcp->width(), srcp->widthMin(), VSigning::UNSIGNED);
2206 }
2207 if (VN_IS(dstp->dtypep(), UnpackArrayDType)) {
2208 streamp = new AstCvtPackedToArray{nodep->fileline(), streamp, dstp->dtypep()};
2209 } else {
2210 UASSERT(sWidth >= dWidth, "sWidth >= dWidth should have caused an error earlier");
2211 if (dWidth == 0) {
2212 streamp = new AstCvtPackedToArray{nodep->fileline(), streamp, dstp->dtypep()};
2213 } else if (sWidth >= dWidth) {
2214 streamp = new AstSel{streamp->fileline(), streamp, sWidth - dWidth, dWidth};
2215 }
2216 }
2217 nodep->lhsp(dstp);
2218 nodep->rhsp(streamp);
2219 nodep->dtypep(dstp->dtypep());
2220 return true;
2221 } else if (m_doV && VN_IS(nodep->lhsp(), StreamR)) {
2222 // The right stream operator on lhs of assignment statement does
2223 // not reorder bits. However, if the rhs is wider than the lhs,
2224 // then we select bits from the left-most, not the right-most.
2225 AstNodeExpr* const streamp = nodep->lhsp()->unlinkFrBack();
2226 AstNodeExpr* const dstp = VN_AS(streamp, StreamR)->lhsp()->unlinkFrBack();
2227 AstNodeExpr* srcp = nodep->rhsp()->unlinkFrBack();
2228 const int sWidth = srcp->width();
2229 const int dWidth = dstp->width();
2230 if (VN_IS(dstp->dtypep(), UnpackArrayDType)) {
2231 const int dstBitWidth
2232 = dWidth * VN_AS(dstp->dtypep(), UnpackArrayDType)->arrayUnpackedElements();
2233 // Handling the case where rhs is wider than lhs. StreamL does not require this
2234 // since the combination of the left streaming operation and the implicit
2235 // truncation in VL_ASSIGN_UNPACK automatically selects the left-most bits.
2236 if (sWidth > dstBitWidth) {
2237 srcp
2238 = new AstSel{streamp->fileline(), srcp, sWidth - dstBitWidth, dstBitWidth};
2239 }
2240 srcp = new AstCvtPackedToArray{nodep->fileline(), srcp, dstp->dtypep()};
2241 } else {
2242 UASSERT(sWidth >= dWidth, "sWidth >= dWidth should have caused an error earlier");
2243 if (dWidth == 0) {
2244 srcp = new AstCvtPackedToArray{nodep->fileline(), srcp, dstp->dtypep()};
2245 } else if (sWidth >= dWidth) {
2246 srcp = new AstSel{streamp->fileline(), srcp, sWidth - dWidth, dWidth};
2247 }
2248 }
2249 nodep->lhsp(dstp);
2250 nodep->rhsp(srcp);
2251 nodep->dtypep(dstp->dtypep());
2252 VL_DO_DANGLING(pushDeletep(streamp), streamp);
2253 // Further reduce, any of the nodes may have more reductions.
2254 return true;
2255 } else if (m_doV && VN_IS(nodep->rhsp(), StreamL)) {
2256 AstNodeDType* const lhsDtypep = nodep->lhsp()->dtypep();
2257 AstStreamL* streamp = VN_AS(nodep->rhsp(), StreamL);
2258 AstNodeExpr* const srcp = streamp->lhsp();
2259 const AstNodeDType* const srcDTypep = srcp->dtypep();
2260 if (VN_IS(srcDTypep, QueueDType) || VN_IS(srcDTypep, DynArrayDType)
2261 || VN_IS(srcDTypep, UnpackArrayDType)) {
2262 streamp->lhsp(new AstCvtArrayToPacked{srcp->fileline(), srcp->unlinkFrBack(),
2263 nodep->dtypep()});
2264 streamp->dtypeFrom(lhsDtypep);
2265 }
2266 } else if (m_doV && replaceAssignMultiSel(nodep)) {
2267 return true;
2268 }
2269 return false;
2270 }
2271 bool replaceJumpGoNext(AstJumpGo* nodep, AstNode* abovep) {
2272 // If JumpGo has an upper JumpBlock that is to same label, then
2273 // code will by normal sequential operation do the JUMPGO and it
2274 // can be removed.
2275 if (nodep->nextp()) return false; // Label jumps other statements
2276 AstJumpBlock* const aboveBlockp = VN_CAST(abovep, JumpBlock);
2277 if (!aboveBlockp) return false;
2278 if (aboveBlockp != nodep->labelp()->blockp()) return false;
2279 if (aboveBlockp->endStmtsp() != nodep->labelp()) return false;
2280 UINFO(4, "JUMPGO => last remove " << nodep << endl);
2281 VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep);
2282 return true;
2283 }
2284
2285 // Boolean replacements
2286 bool operandBoolShift(const AstNode* nodep) {
2287 // boolean test of AND(const,SHIFTR(x,const)) -> test of AND(SHIFTL(x,const), x)
2288 if (!VN_IS(nodep, And)) return false;
2289 if (!VN_IS(VN_AS(nodep, And)->lhsp(), Const)) return false;
2290 if (!VN_IS(VN_AS(nodep, And)->rhsp(), ShiftR)) return false;
2291 const AstShiftR* const shiftp = VN_AS(VN_AS(nodep, And)->rhsp(), ShiftR);
2292 if (!VN_IS(shiftp->rhsp(), Const)) return false;
2293 if (static_cast<uint32_t>(nodep->width()) <= VN_AS(shiftp->rhsp(), Const)->toUInt()) {
2294 return false;
2295 }
2296 return true;
2297 }
2298 void replaceBoolShift(AstNode* nodep) {
2299 if (debug() >= 9) nodep->dumpTree("- bshft_old: ");
2300 AstConst* const andConstp = VN_AS(VN_AS(nodep, And)->lhsp(), Const);
2301 AstNodeExpr* const fromp
2302 = VN_AS(VN_AS(nodep, And)->rhsp(), ShiftR)->lhsp()->unlinkFrBack();
2303 AstConst* const shiftConstp
2304 = VN_AS(VN_AS(VN_AS(nodep, And)->rhsp(), ShiftR)->rhsp(), Const);
2305 V3Number val{andConstp, andConstp->width()};
2306 val.opShiftL(andConstp->num(), shiftConstp->num());
2307 AstAnd* const newp
2308 = new AstAnd{nodep->fileline(), new AstConst{nodep->fileline(), val}, fromp};
2309 // widthMin no longer applicable if different C-expanded width
2310 newp->dtypeSetLogicSized(nodep->width(), VSigning::UNSIGNED);
2311 nodep->replaceWith(newp);
2312 VL_DO_DANGLING(pushDeletep(nodep), nodep);
2313 if (debug() >= 9) newp->dumpTree("- _new: ");
2314 }
2315
2316 void replaceWithSimulation(AstNode* nodep) {
2317 SimulateVisitor simvis;
2318 // Run it - may be unoptimizable due to large for loop, etc
2319 simvis.mainParamEmulate(nodep);
2320 if (!simvis.optimizable()) {
2321 const AstNode* errorp = simvis.whyNotNodep();
2322 if (!errorp) errorp = nodep;
2323 nodep->v3error("Expecting expression to be constant, but can't determine constant for "
2324 << nodep->prettyTypeName() << '\n'
2325 << errorp->warnOther() << "... Location of non-constant "
2326 << errorp->prettyTypeName() << ": " << simvis.whyNotMessage());
2327 VL_DO_DANGLING(replaceZero(nodep), nodep);
2328 } else {
2329 // Fetch the result
2330 AstNode* const valuep = simvis.fetchValueNull(nodep); // valuep is owned by Simulate
2331 UASSERT_OBJ(valuep, nodep, "No value returned from simulation");
2332 // Replace it
2333 AstNode* const newp = valuep->cloneTree(false);
2334 newp->dtypeFrom(nodep);
2335 newp->fileline(nodep->fileline());
2336 UINFO(4, "Simulate->" << newp << endl);
2337 nodep->replaceWith(newp);
2338 VL_DO_DANGLING(pushDeletep(nodep), nodep);
2339 }
2340 }
2341
2342 //----------------------------------------
2343
2344 // VISITORS
2345 void visit(AstNetlist* nodep) override {
2346 // Iterate modules backwards, in bottom-up order. That's faster
2347 iterateChildrenBackwardsConst(nodep);
2348 }
2349 void visit(AstNodeModule* nodep) override {
2350 VL_RESTORER(m_modp);
2351 m_modp = nodep;
2352 m_concswapNames.reset();
2353 iterateChildren(nodep);
2354 }
2355 void visit(AstCFunc* nodep) override {
2356 // No ASSIGNW removals under funcs, we've long eliminated INITIALs
2357 // (We should perhaps rename the assignw's to just assigns)
2358 VL_RESTORER(m_wremove);
2359 m_wremove = false;
2360 iterateChildren(nodep);
2361 }
2362 void visit(AstCLocalScope* nodep) override {
2363 iterateChildren(nodep);
2364 if (!nodep->stmtsp()) {
2365 nodep->unlinkFrBack();
2366 VL_DO_DANGLING(pushDeletep(nodep), nodep);
2367 }
2368 }
2369 void visit(AstScope* nodep) override {
2370 // No ASSIGNW removals under scope, we've long eliminated INITIALs
2371 VL_RESTORER(m_wremove);
2372 VL_RESTORER(m_scopep);
2373 m_wremove = false;
2374 m_scopep = nodep;
2375 iterateChildren(nodep);
2376 }
2377
2378 void swapSides(AstNodeBiCom* nodep) {
2379 // COMMUTATIVE({a},CONST) -> COMMUTATIVE(CONST,{a})
2380 // This simplifies later optimizations
2381 AstNodeExpr* const lhsp = nodep->lhsp()->unlinkFrBackWithNext();
2382 AstNodeExpr* const rhsp = nodep->rhsp()->unlinkFrBackWithNext();
2383 nodep->lhsp(rhsp);
2384 nodep->rhsp(lhsp);
2385 iterate(nodep); // Again?
2386 }
2387
2388 bool containsMemberAccessRecurse(const AstNode* const nodep) {
2389 if (!nodep) return false;
2390 const auto it = m_containsMemberAccess.lower_bound(nodep);
2391 if (it != m_containsMemberAccess.end() && it->first == nodep) return it->second;
2392 bool result = false;
2393 if (VN_IS(nodep, MemberSel) || VN_IS(nodep, MethodCall) || VN_IS(nodep, CMethodCall)) {
2394 result = true;
2395 } else if (const AstNodeFTaskRef* const funcRefp = VN_CAST(nodep, NodeFTaskRef)) {
2396 if (containsMemberAccessRecurse(funcRefp->taskp())) result = true;
2397 } else if (const AstNodeCCall* const funcRefp = VN_CAST(nodep, NodeCCall)) {
2398 if (containsMemberAccessRecurse(funcRefp->funcp())) result = true;
2399 } else if (const AstNodeFTask* const funcp = VN_CAST(nodep, NodeFTask)) {
2400 // Assume that it has a member access
2401 if (funcp->recursive()) result = true;
2402 } else if (const AstCFunc* const funcp = VN_CAST(nodep, CFunc)) {
2403 if (funcp->recursive()) result = true;
2404 }
2405 if (!result) {
2406 result = containsMemberAccessRecurse(nodep->op1p())
2407 || containsMemberAccessRecurse(nodep->op2p())
2408 || containsMemberAccessRecurse(nodep->op3p())
2409 || containsMemberAccessRecurse(nodep->op4p());
2410 }
2411 if (!result && !VN_IS(nodep, NodeFTask)
2412 && !VN_IS(nodep, CFunc) // don't enter into next function
2413 && containsMemberAccessRecurse(nodep->nextp())) {
2414 result = true;
2415 }
2416 m_containsMemberAccess.insert(it, std::make_pair(nodep, result));
2417 return result;
2418 }
2419
2420 bool matchBiopToBitwise(AstNodeBiop* const nodep) {
2421 if (!m_convertLogicToBit) return false;
2422 if (!nodep->lhsp()->width1()) return false;
2423 if (!nodep->rhsp()->width1()) return false;
2424 if (!nodep->isPure()) return false;
2425 if (containsMemberAccessRecurse(nodep)) return false;
2426 return true;
2427 }
2428 bool matchConcatRand(AstConcat* nodep) {
2429 // CONCAT(RAND, RAND) - created by Chisel code
2430 AstRand* const aRandp = VN_CAST(nodep->lhsp(), Rand);
2431 AstRand* const bRandp = VN_CAST(nodep->rhsp(), Rand);
2432 if (!aRandp || !bRandp) return false;
2433 if (!aRandp->combinable(bRandp)) return false;
2434 UINFO(4, "Concat(Rand,Rand) => Rand: " << nodep << endl);
2435 aRandp->dtypeFrom(nodep); // I.e. the total width
2436 nodep->replaceWith(aRandp->unlinkFrBack());
2437 VL_DO_DANGLING(pushDeletep(nodep), nodep);
2438 return true;
2439 }
2440 bool matchSelRand(AstSel* nodep) {
2441 // SEL(RAND) - created by Chisel code
2442 AstRand* const aRandp = VN_CAST(nodep->fromp(), Rand);
2443 if (!aRandp) return false;
2444 if (aRandp->seedp()) return false;
2445 UINFO(4, "Sel(Rand) => Rand: " << nodep << endl);
2446 aRandp->dtypeFrom(nodep); // I.e. the total width
2447 nodep->replaceWith(aRandp->unlinkFrBack());
2448 VL_DO_DANGLING(pushDeletep(nodep), nodep);
2449 return true;
2450 }
2451 int operandConcatMove(AstConcat* nodep) {
2452 // CONCAT under concat (See moveConcat)
2453 // Return value: true indicates to do it; 2 means move to LHS
2454 const AstConcat* const abConcp = VN_CAST(nodep->lhsp(), Concat);
2455 const AstConcat* const bcConcp = VN_CAST(nodep->rhsp(), Concat);
2456 if (!abConcp && !bcConcp) return 0;
2457 if (bcConcp) {
2458 AstNodeExpr* const ap = nodep->lhsp();
2459 AstNodeExpr* const bp = bcConcp->lhsp();
2460 // If a+b == 32,64,96 etc, then we want to have a+b together on LHS
2461 if (VL_BITBIT_I(ap->width() + bp->width()) == 0) return 2; // Transform 2: to abConc
2462 } else { // abConcp
2463 // Unless lhs is already 32 bits due to above, reorder it
2464 if (VL_BITBIT_I(nodep->lhsp()->width()) != 0) return 1; // Transform 1: to bcConc
2465 }
2466 return 0; // ok
2467 }
2468 void moveConcat(AstConcat* nodep) {
2469 // 1: CONCAT(CONCAT({a},{b}),{c}) -> CONCAT({a},CONCAT({b}, {c}))
2470 // or 2: CONCAT({a}, CONCAT({b},{c})) -> CONCAT(CONCAT({a},{b}),{c})
2471 // Because the lhs of a concat needs a shift but the rhs doesn't,
2472 // putting additional CONCATs on the RHS leads to fewer assembler operations.
2473 // However, we'll end up with lots of wide moves if we make huge trees
2474 // like that, so on 32 bit boundaries, we'll do the opposite form.
2475 UINFO(4, "Move concat: " << nodep << endl);
2476 if (operandConcatMove(nodep) > 1) {
2477 AstNodeExpr* const ap = nodep->lhsp()->unlinkFrBack();
2478 AstConcat* const bcConcp = VN_AS(nodep->rhsp(), Concat);
2479 bcConcp->unlinkFrBack();
2480 AstNodeExpr* const bp = bcConcp->lhsp()->unlinkFrBack();
2481 AstNodeExpr* const cp = bcConcp->rhsp()->unlinkFrBack();
2482 AstConcat* const abConcp = new AstConcat{bcConcp->fileline(), ap, bp};
2483 nodep->lhsp(abConcp);
2484 nodep->rhsp(cp);
2485 // If bp was a concat, then we have this exact same form again!
2486 // Recurse rather then calling node->iterate to prevent 2^n recursion!
2487 if (operandConcatMove(abConcp)) moveConcat(abConcp);
2488 VL_DO_DANGLING(pushDeletep(bcConcp), bcConcp);
2489 } else {
2490 AstConcat* const abConcp = VN_AS(nodep->lhsp(), Concat);
2491 abConcp->unlinkFrBack();
2492 AstNodeExpr* const ap = abConcp->lhsp()->unlinkFrBack();
2493 AstNodeExpr* const bp = abConcp->rhsp()->unlinkFrBack();
2494 AstNodeExpr* const cp = nodep->rhsp()->unlinkFrBack();
2495 AstConcat* const bcConcp = new AstConcat{abConcp->fileline(), bp, cp};
2496 nodep->lhsp(ap);
2497 nodep->rhsp(bcConcp);
2498 if (operandConcatMove(bcConcp)) moveConcat(bcConcp);
2499 VL_DO_DANGLING(pushDeletep(abConcp), abConcp);
2500 }
2501 }
2502
2503 // Special cases
2504 void visit(AstConst*) override {} // Already constant
2505
2506 void visit(AstCell* nodep) override {
2507 if (m_params) {
2508 iterateAndNextNull(nodep->paramsp());
2509 } else {
2510 iterateChildren(nodep);
2511 }
2512 }
2513 void visit(AstClassOrPackageRef* nodep) override { iterateChildren(nodep); }
2514 void visit(AstPin* nodep) override { iterateChildren(nodep); }
2515
2516 void replaceLogEq(AstLogEq* nodep) {
2517 // LOGEQ(a,b) => AstLogAnd{AstLogOr{AstLogNot{a},b},AstLogOr{AstLogNot{b},a}}
2518 AstNodeExpr* const lhsp = nodep->lhsp()->unlinkFrBack();
2519 AstNodeExpr* const rhsp = nodep->rhsp()->unlinkFrBack();
2520 // Do exactly as IEEE says, might result in extra terms, so in future may do differently
2521 AstLogAnd* const newp = new AstLogAnd{
2522 nodep->fileline(),
2523 new AstLogOr{nodep->fileline(), new AstLogNot{nodep->fileline(), lhsp}, rhsp},
2524 new AstLogOr{nodep->fileline(),
2525 new AstLogNot{nodep->fileline(), rhsp->cloneTreePure(false)},
2526 lhsp->cloneTreePure(false)}};
2527 newp->dtypeFrom(nodep);
2528 nodep->replaceWith(newp);
2529 VL_DO_DANGLING(pushDeletep(nodep), nodep);
2530 }
2531
2532 void replaceSelSel(AstSel* nodep) {
2533 // SEL(SEL({x},a,b),c,d) => SEL({x},a+c,d)
2534 AstSel* const belowp = VN_AS(nodep->fromp(), Sel);
2535 AstNodeExpr* const fromp = belowp->fromp()->unlinkFrBack();
2536 AstNodeExpr* const widthp = nodep->widthp()->unlinkFrBack();
2537 AstNodeExpr* const lsb1p = nodep->lsbp()->unlinkFrBack();
2538 AstNodeExpr* const lsb2p = belowp->lsbp()->unlinkFrBack();
2539 // Eliminate lower range
2540 UINFO(4, "Elim Lower range: " << nodep << endl);
2541 AstNodeExpr* newlsbp;
2542 if (VN_IS(lsb1p, Const) && VN_IS(lsb2p, Const)) {
2543 newlsbp = new AstConst{lsb1p->fileline(),
2544 VN_AS(lsb1p, Const)->toUInt() + VN_AS(lsb2p, Const)->toUInt()};
2545 VL_DO_DANGLING(pushDeletep(lsb1p), lsb1p);
2546 VL_DO_DANGLING(pushDeletep(lsb2p), lsb2p);
2547 } else {
2548 // Width is important, we need the width of the fromp's expression, not the
2549 // potentially smaller lsb1p's width, but don't insert a redundant AstExtend.
2550 // Note that due to some sloppiness in earlier passes, lsb1p might actually be wider,
2551 // so extend to the wider type.
2552 AstNodeExpr* const widep = lsb1p->width() > lsb2p->width() ? lsb1p : lsb2p;
2553 AstNodeExpr* const lhsp = widep->width() > lsb2p->width()
2554 ? new AstExtend{lsb2p->fileline(), lsb2p}
2555 : lsb2p;
2556 AstNodeExpr* const rhsp = widep->width() > lsb1p->width()
2557 ? new AstExtend{lsb1p->fileline(), lsb1p}
2558 : lsb1p;
2559 lhsp->dtypeFrom(widep);
2560 rhsp->dtypeFrom(widep);
2561 newlsbp = new AstAdd{lsb1p->fileline(), lhsp, rhsp};
2562 newlsbp->dtypeFrom(widep);
2563 }
2564 AstSel* const newp = new AstSel{nodep->fileline(), fromp, newlsbp, widthp};
2565 nodep->replaceWith(newp);
2566 VL_DO_DANGLING(pushDeletep(nodep), nodep);
2567 }
2568
2569 void replaceSelConcat(AstSel* nodep) {
2570 // SEL(CONCAT(a,b),c,d) => SEL(a or b, . .)
2571 AstConcat* const conp = VN_AS(nodep->fromp(), Concat);
2572 AstNodeExpr* const conLhsp = conp->lhsp();
2573 AstNodeExpr* const conRhsp = conp->rhsp();
2574 if (static_cast<int>(nodep->lsbConst()) >= conRhsp->width()) {
2575 conLhsp->unlinkFrBack();
2576 AstSel* const newp
2577 = new AstSel{nodep->fileline(), conLhsp, nodep->lsbConst() - conRhsp->width(),
2578 nodep->widthConst()};
2579 nodep->replaceWith(newp);
2580 } else if (static_cast<int>(nodep->msbConst()) < conRhsp->width()) {
2581 conRhsp->unlinkFrBack();
2582 AstSel* const newp
2583 = new AstSel{nodep->fileline(), conRhsp, nodep->lsbConst(), nodep->widthConst()};
2584 nodep->replaceWith(newp);
2585 } else {
2586 // Yuk, split between the two
2587 conRhsp->unlinkFrBack();
2588 conLhsp->unlinkFrBack();
2589 AstConcat* const newp
2590 = new AstConcat{nodep->fileline(),
2591 new AstSel{nodep->fileline(), conLhsp, 0,
2592 nodep->msbConst() - conRhsp->width() + 1},
2593 new AstSel{nodep->fileline(), conRhsp, nodep->lsbConst(),
2594 conRhsp->width() - nodep->lsbConst()}};
2595 nodep->replaceWith(newp);
2596 }
2597 VL_DO_DANGLING(pushDeletep(nodep), nodep);
2598 }
2599 bool operandSelReplicate(AstSel* nodep) {
2600 // SEL(REPLICATE(from,rep),lsb,width) => SEL(from,0,width) as long
2601 // as SEL's width <= b's width
2602 AstReplicate* const repp = VN_AS(nodep->fromp(), Replicate);
2603 AstNodeExpr* const fromp = repp->srcp();
2604 AstConst* const lsbp = VN_CAST(nodep->lsbp(), Const);
2605 if (!lsbp) return false;
2606 AstNodeExpr* const widthp = nodep->widthp();
2607 if (!VN_IS(widthp, Const)) return false;
2608 UASSERT_OBJ(fromp->width(), nodep, "Not widthed");
2609 if ((lsbp->toUInt() / fromp->width())
2610 != ((lsbp->toUInt() + nodep->width() - 1) / fromp->width())) {
2611 return false;
2612 }
2613 //
2614 fromp->unlinkFrBack();
2615 widthp->unlinkFrBack();
2616 AstSel* const newp
2617 = new AstSel{nodep->fileline(), fromp,
2618 new AstConst{lsbp->fileline(), lsbp->toUInt() % fromp->width()}, widthp};
2619 newp->dtypeFrom(nodep);
2620 nodep->replaceWith(newp);
2621 VL_DO_DANGLING(pushDeletep(nodep), nodep);
2622 return true;
2623 }
2624 bool operandRepRep(AstReplicate* nodep) {
2625 // REPLICATE(REPLICATE2(from2,cnt2),cnt1) => REPLICATE(from2,(cnt1+cnt2))
2626 AstReplicate* const rep2p = VN_AS(nodep->srcp(), Replicate);
2627 AstNodeExpr* const from2p = rep2p->srcp();
2628 AstConst* const cnt1p = VN_CAST(nodep->countp(), Const);
2629 if (!cnt1p) return false;
2630 AstConst* const cnt2p = VN_CAST(rep2p->countp(), Const);
2631 if (!cnt2p) return false;
2632 //
2633 from2p->unlinkFrBack();
2634 cnt1p->unlinkFrBack();
2635 cnt2p->unlinkFrBack();
2636 AstReplicate* const newp
2637 = new AstReplicate{nodep->fileline(), from2p, cnt1p->toUInt() * cnt2p->toUInt()};
2638 newp->dtypeFrom(nodep);
2639 nodep->replaceWith(newp);
2640 VL_DO_DANGLING(pushDeletep(nodep), nodep);
2641 return true;
2642 }
2643 bool operandConcatSame(AstConcat* nodep) {
2644 // CONCAT(fromp,fromp) -> REPLICATE(fromp,1+1)
2645 // CONCAT(REP(fromp,cnt1),fromp) -> REPLICATE(fromp,cnt1+1)
2646 // CONCAT(fromp,REP(fromp,cnt1)) -> REPLICATE(fromp,1+cnt1)
2647 // CONCAT(REP(fromp,cnt1),REP(fromp,cnt2)) -> REPLICATE(fromp,cnt1+cnt2)
2648 AstNodeExpr* from1p = nodep->lhsp();
2649 uint32_t cnt1 = 1;
2650 AstNodeExpr* from2p = nodep->rhsp();
2651 uint32_t cnt2 = 1;
2652 if (VN_IS(from1p, Replicate)) {
2653 AstConst* const cnt1p = VN_CAST(VN_CAST(from1p, Replicate)->countp(), Const);
2654 if (!cnt1p) return false;
2655 from1p = VN_AS(from1p, Replicate)->srcp();
2656 cnt1 = cnt1p->toUInt();
2657 }
2658 if (VN_IS(from2p, Replicate)) {
2659 AstConst* const cnt2p = VN_CAST(VN_CAST(from2p, Replicate)->countp(), Const);
2660 if (!cnt2p) return false;
2661 from2p = VN_AS(from2p, Replicate)->srcp();
2662 cnt2 = cnt2p->toUInt();
2663 }
2664 if (!operandsSame(from1p, from2p)) return false;
2665 //
2666 from1p->unlinkFrBack();
2667 AstReplicate* const newp = new AstReplicate{nodep->fileline(), from1p, cnt1 + cnt2};
2668 newp->dtypeFrom(nodep);
2669 nodep->replaceWith(newp);
2670 VL_DO_DANGLING(pushDeletep(nodep), nodep);
2671 return true;
2672 }
2673 void replaceSelIntoBiop(AstSel* nodep) {
2674 // SEL(BUFIF1(a,b),1,bit) => BUFIF1(SEL(a,1,bit),SEL(b,1,bit))
2675 AstNodeBiop* const fromp = VN_AS(nodep->fromp()->unlinkFrBack(), NodeBiop);
2676 UASSERT_OBJ(fromp, nodep, "Called on non biop");
2677 AstNodeExpr* const lsbp = nodep->lsbp()->unlinkFrBack();
2678 AstNodeExpr* const widthp = nodep->widthp()->unlinkFrBack();
2679 //
2680 AstNodeExpr* const bilhsp = fromp->lhsp()->unlinkFrBack();
2681 AstNodeExpr* const birhsp = fromp->rhsp()->unlinkFrBack();
2682 //
2683 fromp->lhsp(new AstSel{nodep->fileline(), bilhsp, lsbp->cloneTreePure(true),
2684 widthp->cloneTreePure(true)});
2685 fromp->rhsp(new AstSel{nodep->fileline(), birhsp, lsbp, widthp});
2686 fromp->dtypeFrom(nodep);
2687 nodep->replaceWith(fromp);
2688 VL_DO_DANGLING(pushDeletep(nodep), nodep);
2689 }
2690 void replaceSelIntoUniop(AstSel* nodep) {
2691 // SEL(NOT(a),1,bit) => NOT(SEL(a,bit))
2692 AstNodeUniop* const fromp = VN_AS(nodep->fromp()->unlinkFrBack(), NodeUniop);
2693 UASSERT_OBJ(fromp, nodep, "Called on non biop");
2694 AstNodeExpr* const lsbp = nodep->lsbp()->unlinkFrBack();
2695 AstNodeExpr* const widthp = nodep->widthp()->unlinkFrBack();
2696 //
2697 AstNodeExpr* const bilhsp = fromp->lhsp()->unlinkFrBack();
2698 //
2699 fromp->lhsp(new AstSel{nodep->fileline(), bilhsp, lsbp, widthp});
2700 fromp->dtypeFrom(nodep);
2701 nodep->replaceWith(fromp);
2702 VL_DO_DANGLING(pushDeletep(nodep), nodep);
2703 }
2704
2705 void visit(AstAttrOf* nodep) override {
2706 VL_RESTORER(m_attrp);
2707 m_attrp = nodep;
2708 iterateChildren(nodep);
2709 }
2710
2711 void visit(AstArraySel* nodep) override {
2712 iterateAndNextNull(nodep->bitp());
2713 if (VN_IS(nodep->bitp(), Const)
2714 && VN_IS(nodep->fromp(), VarRef)
2715 // Need to make sure it's an array object so don't mis-allow a constant (bug509.)
2716 && VN_AS(nodep->fromp(), VarRef)->varp()
2717 && VN_IS(VN_AS(nodep->fromp(), VarRef)->varp()->valuep(), InitArray)) {
2718 m_selp = nodep; // Ask visit(AstVarRef) to replace varref with const
2719 }
2720 iterateAndNextNull(nodep->fromp());
2721 if (VN_IS(nodep->fromp(), Const)) { // It did.
2722 if (!m_selp) {
2723 nodep->v3error("Illegal assignment of constant to unpacked array");
2724 } else {
2725 AstNode* const fromp = nodep->fromp()->unlinkFrBack();
2726 nodep->replaceWith(fromp);
2727 if (VN_IS(fromp->dtypep()->skipRefp(), NodeArrayDType)) {
2728 // Strip off array to find what array references
2729 fromp->dtypeFrom(
2730 VN_AS(fromp->dtypep()->skipRefp(), NodeArrayDType)->subDTypep());
2731 }
2732 VL_DO_DANGLING(pushDeletep(nodep), nodep);
2733 }
2734 }
2735 m_selp = nullptr;
2736 }
2737 void visit(AstCAwait* nodep) override {
2738 m_hasJumpDelay = true;
2739 iterateChildren(nodep);
2740 }
2741 void visit(AstNodeVarRef* nodep) override {
2742 iterateChildren(nodep);
2743 UASSERT_OBJ(nodep->varp(), nodep, "Not linked");
2744 bool did = false;
2745 if (m_doV && nodep->varp()->valuep() && !m_attrp) {
2746 // if (debug()) valuep->dumpTree("- visitvaref: ");
2747 iterateAndNextNull(nodep->varp()->valuep()); // May change nodep->varp()->valuep()
2748 AstNode* const valuep = nodep->varp()->valuep();
2749 if (nodep->access().isReadOnly()
2750 && ((!m_params // Can reduce constant wires into equations
2751 && m_doNConst
2752 && v3Global.opt.fConst()
2753 // Default value, not a "known" constant for this usage
2754 && !nodep->varp()->isClassMember() && !nodep->varp()->sensIfacep()
2755 && !(nodep->varp()->isFuncLocal() && nodep->varp()->isNonOutput())
2756 && !nodep->varp()->noSubst() && !nodep->varp()->isSigPublic())
2757 || nodep->varp()->isParam())) {
2758 if (operandConst(valuep)) {
2759 const V3Number& num = VN_AS(valuep, Const)->num();
2760 // UINFO(2,"constVisit "<<cvtToHex(valuep)<<" "<<num<<endl);
2761 VL_DO_DANGLING(replaceNum(nodep, num), nodep);
2762 did = true;
2763 } else if (m_selp && VN_IS(valuep, InitArray)) {
2764 AstInitArray* const initarp = VN_AS(valuep, InitArray);
2765 const uint32_t bit = m_selp->bitConst();
2766 AstNode* const itemp = initarp->getIndexDefaultedValuep(bit);
2767 if (VN_IS(itemp, Const)) {
2768 const V3Number& num = VN_AS(itemp, Const)->num();
2769 // UINFO(2,"constVisit "<<cvtToHex(valuep)<<" "<<num<<endl);
2770 VL_DO_DANGLING(replaceNum(nodep, num), nodep);
2771 did = true;
2772 }
2773 } else if (m_params && VN_IS(valuep, InitArray)) {
2774 // Allow parameters to pass arrays
2775 // Earlier recursion of InitArray made sure each array value is constant
2776 // This exception is fairly fragile, i.e. doesn't
2777 // support arrays of arrays or other stuff
2778 AstNode* const newp = valuep->cloneTree(false);
2779 nodep->replaceWith(newp);
2780 VL_DO_DANGLING(pushDeletep(nodep), nodep);
2781 did = true;
2782 } else if (nodep->varp()->isParam() && VN_IS(valuep, Unbounded)) {
2783 AstNode* const newp = valuep->cloneTree(false);
2784 nodep->replaceWith(newp);
2785 VL_DO_DANGLING(pushDeletep(nodep), nodep);
2786 did = true;
2787 }
2788 }
2789 }
2790 if (!did && m_required) {
2791 nodep->v3error("Expecting expression to be constant, but variable isn't const: "
2792 << nodep->varp()->prettyNameQ());
2793 }
2794 }
2795 void visit(AstExprStmt* nodep) override {
2796 iterateChildren(nodep);
2797 if (!AstNode::afterCommentp(nodep->stmtsp())) {
2798 UINFO(8, "ExprStmt(...) " << nodep << " " << nodep->resultp() << endl);
2799 nodep->replaceWith(nodep->resultp()->unlinkFrBack());
2800 VL_DO_DANGLING(pushDeletep(nodep), nodep);
2801 // Removing the ExprStmt might have made something impure above now pure
2802 }
2803 }
2804 void visit(AstEnumItemRef* nodep) override {
2805 iterateChildren(nodep);
2806 UASSERT_OBJ(nodep->itemp(), nodep, "Not linked");
2807 bool did = false;
2808 if (nodep->itemp()->valuep()) {
2809 // if (debug()) nodep->itemp()->valuep()->dumpTree("- visitvaref: ");
2810 if (nodep->itemp()->user4()) {
2811 nodep->v3error("Recursive enum value: " << nodep->itemp()->prettyNameQ());
2812 } else {
2813 nodep->itemp()->user4(true);
2814 iterateAndNextNull(nodep->itemp()->valuep());
2815 nodep->itemp()->user4(false);
2816 }
2817 if (AstConst* const valuep = VN_CAST(nodep->itemp()->valuep(), Const)) {
2818 const V3Number& num = valuep->num();
2819 VL_DO_DANGLING(replaceNum(nodep, num), nodep);
2820 did = true;
2821 }
2822 }
2823 if (!did && m_required) {
2824 nodep->v3error("Expecting expression to be constant, but enum value isn't const: "
2825 << nodep->itemp()->prettyNameQ());
2826 }
2827 }
2828
2829 // void visit(AstCvtPackString* nodep) override {
2830 // Not constant propagated (for today) because AstNodeExpr::isOpaque is set
2831 // Someday if lower is constant, convert to quoted "string".
2832
2833 bool onlySenItemInSenTree(AstSenItem* nodep) {
2834 // Only one if it's not in a list
2835 return (!nodep->nextp() && nodep->backp()->nextp() != nodep);
2836 }
2837 void visit(AstSenItem* nodep) override {
2838 iterateChildren(nodep);
2839 if (m_doNConst
2840 && !v3Global.opt.timing().isSetTrue() // If --timing, V3Sched would turn this into an
2841 // infinite loop. See #5080
2842 && (VN_IS(nodep->sensp(), Const) || VN_IS(nodep->sensp(), EnumItemRef)
2843 || (nodep->varrefp() && nodep->varrefp()->varp()->isParam()))) {
2844 // Constants in sensitivity lists may be removed (we'll simplify later)
2845 if (nodep->isClocked()) { // A constant can never get a pos/negedge
2846 if (onlySenItemInSenTree(nodep)) {
2847 if (nodep->edgeType() == VEdgeType::ET_CHANGED) {
2848 // TODO: This really is dodgy, as strictly compliant simulators will not
2849 // execute this block, but but t_func_check relies on it
2850 nodep->replaceWith(
2851 new AstSenItem{nodep->fileline(), AstSenItem::Initial{}});
2852 } else {
2853 nodep->replaceWith(new AstSenItem{nodep->fileline(), AstSenItem::Never{}});
2854 }
2855 VL_DO_DANGLING(pushDeletep(nodep), nodep);
2856 } else {
2857 VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep);
2858 }
2859 } else { // Otherwise it may compute a result that needs to settle out
2860 nodep->replaceWith(new AstSenItem{nodep->fileline(), AstSenItem::Combo{}});
2861 VL_DO_DANGLING(pushDeletep(nodep), nodep);
2862 }
2863 } else if (m_doNConst && VN_IS(nodep->sensp(), Not)) {
2864 // V3Gate may propagate NOTs into clocks... Just deal with it
2865 AstNode* const sensp = nodep->sensp();
2866 AstNode* lastSensp = sensp;
2867 bool invert = false;
2868 while (VN_IS(lastSensp, Not)) {
2869 lastSensp = VN_AS(lastSensp, Not)->lhsp();
2870 invert = !invert;
2871 }
2872 UINFO(8, "senItem(NOT...) " << nodep << " " << invert << endl);
2873 if (invert) nodep->edgeType(nodep->edgeType().invert());
2874 sensp->replaceWith(lastSensp->unlinkFrBack());
2875 VL_DO_DANGLING(pushDeletep(sensp), sensp);
2876 }
2877 }
2878
2879 class SenItemCmp final {
2880 static int cmp(const AstNodeExpr* ap, const AstNodeExpr* bp) {
2881 const VNType aType = ap->type();
2882 const VNType bType = bp->type();
2883 if (aType != bType) return static_cast<int>(bType) - static_cast<int>(aType);
2884
2885 if (const AstVarRef* const aRefp = VN_CAST(ap, VarRef)) {
2886 const AstVarRef* const bRefp = VN_AS(bp, VarRef);
2887 // Looks visually better if we keep sorted by name
2888 if (aRefp->name() < bRefp->name()) return -1;
2889 if (aRefp->name() > bRefp->name()) return 1;
2890 // But might be same name with different scopes
2891 if (aRefp->varScopep() < bRefp->varScopep()) return -1;
2892 if (aRefp->varScopep() > bRefp->varScopep()) return 1;
2893 // Or rarely, different data types
2894 if (aRefp->dtypep() < bRefp->dtypep()) return -1;
2895 if (aRefp->dtypep() > bRefp->dtypep()) return 1;
2896 return 0;
2897 }
2898
2899 if (const AstConst* const aConstp = VN_CAST(ap, Const)) {
2900 const AstConst* const bConstp = VN_AS(bp, Const);
2901 if (aConstp->toUQuad() < bConstp->toUQuad()) return -1;
2902 if (aConstp->toUQuad() > bConstp->toUQuad()) return 1;
2903 return 0;
2904 }
2905
2906 if (const AstNodeBiop* const aBiOpp = VN_CAST(ap, NodeBiop)) {
2907 const AstNodeBiop* const bBiOpp = VN_AS(bp, NodeBiop);
2908 // Compare RHSs first as LHS might be const, but the variable term should become
2909 // adjacent for optimization if identical.
2910 if (const int c = cmp(aBiOpp->rhsp(), bBiOpp->rhsp())) return c;
2911 return cmp(aBiOpp->lhsp(), bBiOpp->lhsp());
2912 }
2913
2914 if (const AstCMethodHard* const aCallp = VN_CAST(ap, CMethodHard)) {
2915 const AstCMethodHard* const bCallp = VN_AS(bp, CMethodHard);
2916 if (aCallp->name() < bCallp->name()) return -1;
2917 if (aCallp->name() > bCallp->name()) return 1;
2918 if (const int c = cmp(aCallp->fromp(), bCallp->fromp())) return c;
2919 AstNodeExpr* aPinsp = aCallp->pinsp();
2920 AstNodeExpr* bPinsp = bCallp->pinsp();
2921 while (aPinsp && bPinsp) {
2922 if (const int c = cmp(aPinsp, bPinsp)) return c;
2923 aPinsp = VN_AS(aPinsp->nextp(), NodeExpr);
2924 bPinsp = VN_AS(bPinsp->nextp(), NodeExpr);
2925 }
2926 return aPinsp ? -1 : bPinsp ? 1 : 0;
2927 }
2928
2929 return 0;
2930 }
2931
2932 public:
2933 bool operator()(const AstSenItem* lhsp, const AstSenItem* rhsp) const {
2934 AstNodeExpr* const lSensp = lhsp->sensp();
2935 AstNodeExpr* const rSensp = rhsp->sensp();
2936 if (lSensp && rSensp) {
2937 // If both terms have sensitivity expressions, recursively compare them
2938 if (const int c = cmp(lSensp, rSensp)) return c < 0;
2939 } else if (lSensp || rSensp) {
2940 // Terms with sensitivity expressions come after those without
2941 return rSensp;
2942 }
2943 // Finally sort by edge, AFTER variable, as we want multiple edges for same var
2944 // adjacent. note the SenTree optimizer requires this order (more general first,
2945 // less general last)
2946 return lhsp->edgeType() < rhsp->edgeType();
2947 }
2948 };
2949
2950 void visit(AstSenTree* nodep) override {
2951 iterateChildren(nodep);
2952 if (m_doExpensive) {
2953 // cout<<endl; nodep->dumpTree("- ssin: ");
2954 // Optimize ideas for the future:
2955 // SENTREE(... SENGATE(x,a), SENGATE(SENITEM(x),b) ...) => SENGATE(x,OR(a,b))
2956
2957 // SENTREE(... SENITEM(x), SENGATE(SENITEM(x),*) ...) => SENITEM(x)
2958 // Do we need the SENITEM's to be identical? No because we're
2959 // ORing between them; we just need to ensure that the result is at
2960 // least as frequently activating. So we
2961 // SENGATE(SENITEM(x)) -> SENITEM(x), then let it collapse with the
2962 // other SENITEM(x).
2963
2964 // Mark x in SENITEM(x)
2965 for (AstSenItem* senp = nodep->sensesp(); senp; senp = VN_AS(senp->nextp(), SenItem)) {
2966 if (senp->varrefp() && senp->varrefp()->varScopep()) {
2967 senp->varrefp()->varScopep()->user4(1);
2968 }
2969 }
2970
2971 // Pass 1: Sort the sensitivity items so "posedge a or b" and "posedge b or a" and
2972 // similar, optimizable expressions end up next to each other.
2973 for (AstSenItem *nextp, *senp = nodep->sensesp(); senp; senp = nextp) {
2974 nextp = VN_AS(senp->nextp(), SenItem);
2975 // cppcheck-suppress unassignedVariable // cppcheck bug
2976 const SenItemCmp cmp;
2977 if (nextp && !cmp(senp, nextp)) {
2978 // Something's out of order, sort it
2979 senp = nullptr;
2980 std::vector<AstSenItem*> vec;
2981 for (AstSenItem* senp = nodep->sensesp(); senp;
2982 senp = VN_AS(senp->nextp(), SenItem)) {
2983 vec.push_back(senp);
2984 }
2985 stable_sort(vec.begin(), vec.end(), SenItemCmp());
2986 for (const auto& ip : vec) ip->unlinkFrBack();
2987 for (const auto& ip : vec) nodep->addSensesp(ip);
2988 break;
2989 }
2990 }
2991
2992 // Pass 2, remove duplicates and simplify adjacent terms if possible
2993 for (AstSenItem *senp = nodep->sensesp(), *nextp; senp; senp = nextp) {
2994 nextp = VN_AS(senp->nextp(), SenItem);
2995 if (!nextp) break;
2996 AstSenItem* const lItemp = senp;
2997 AstSenItem* const rItemp = nextp;
2998 AstNodeExpr* const lSenp = lItemp->sensp();
2999 AstNodeExpr* const rSenp = rItemp->sensp();
3000 if (!lSenp || !rSenp) continue;
3001
3002 if (lSenp->sameGateTree(rSenp)) {
3003 // POSEDGE or NEGEDGE -> BOTHEDGE. (We've sorted POSEDGE, before NEGEDGE, so we
3004 // do not need to test for the opposite orders.)
3005 if (lItemp->edgeType() == VEdgeType::ET_POSEDGE
3006 && rItemp->edgeType() == VEdgeType::ET_NEGEDGE) {
3007 // Make both terms BOTHEDGE, the second will be removed below
3008 lItemp->edgeType(VEdgeType::ET_BOTHEDGE);
3009 rItemp->edgeType(VEdgeType::ET_BOTHEDGE);
3010 }
3011
3012 // Remove identical expressions
3013 if (lItemp->edgeType() == rItemp->edgeType()) {
3014 VL_DO_DANGLING(pushDeletep(rItemp->unlinkFrBack()), rItemp);
3015 nextp = lItemp;
3016 }
3017
3018 continue;
3019 }
3020
3021 // Not identical terms, check if they can be combined
3022 if (lSenp->width() != rSenp->width()) continue;
3023 if (AstAnd* const lAndp = VN_CAST(lSenp, And)) {
3024 if (AstAnd* const rAndp = VN_CAST(rSenp, And)) {
3025 if (AstConst* const lConstp = VN_CAST(lAndp->lhsp(), Const)) {
3026 if (AstConst* const rConstp = VN_CAST(rAndp->lhsp(), Const)) {
3027 if (lAndp->rhsp()->sameTree(rAndp->rhsp())) {
3028 const V3Number lNum{lConstp->num()};
3029 lConstp->num().opOr(lNum, rConstp->num());
3030 // Remove redundant term
3031 VL_DO_DANGLING(pushDeletep(rItemp->unlinkFrBack()), rItemp);
3032 nextp = lItemp;
3033 }
3034 }
3035 }
3036 }
3037 }
3038 }
3039 }
3040 }
3041
3042 //-----
3043 // Zero elimination
3044 void visit(AstNodeAssign* nodep) override {
3045 iterateChildren(nodep);
3046 if (nodep->timingControlp()) m_hasJumpDelay = true;
3047 if (m_doNConst && replaceNodeAssign(nodep)) return;
3048 }
3049 void visit(AstAssignAlias* nodep) override {
3050 // Don't perform any optimizations, keep the alias around
3051 }
3052 void visit(AstAssignVarScope* nodep) override {
3053 // Don't perform any optimizations, the node won't be linked yet
3054 }
3055 void visit(AstAssignW* nodep) override {
3056 iterateChildren(nodep);
3057 if (m_doNConst && replaceNodeAssign(nodep)) return;
3058 AstNodeVarRef* const varrefp = VN_CAST(
3059 nodep->lhsp(),
3060 VarRef); // Not VarXRef, as different refs may set different values to each hierarchy
3061 if (m_wremove && !m_params && m_doNConst && m_modp && operandConst(nodep->rhsp())
3062 && !VN_AS(nodep->rhsp(), Const)->num().isFourState()
3063 && varrefp // Don't do messes with BITREFs/ARRAYREFs
3064 && !varrefp->varp()->hasStrengthAssignment() // Strengths are resolved in V3Tristate
3065 && !varrefp->varp()->valuep() // Not already constified
3066 && !varrefp->varScopep() // Not scoped (or each scope may have different initial val.)
3067 && !varrefp->varp()->isForced() // Not forced (not really a constant)
3068 ) {
3069 // ASSIGNW (VARREF, const) -> INITIAL ( ASSIGN (VARREF, const) )
3070 UINFO(4, "constAssignW " << nodep << endl);
3071 // Make a initial assignment
3072 AstNodeExpr* const exprp = nodep->rhsp()->unlinkFrBack();
3073 varrefp->unlinkFrBack();
3074 AstInitial* const newinitp = new AstInitial{
3075 nodep->fileline(), new AstAssign{nodep->fileline(), varrefp, exprp}};
3076 m_modp->addStmtsp(newinitp);
3077 VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep);
3078 // Set the initial value right in the variable so we can constant propagate
3079 AstNode* const initvaluep = exprp->cloneTree(false);
3080 varrefp->varp()->valuep(initvaluep);
3081 }
3082 }
3083 void visit(AstRelease* nodep) override {
3084 if (AstConcat* const concatp = VN_CAST(nodep->lhsp(), Concat)) {
3085 FileLine* const flp = nodep->fileline();
3086 AstRelease* const newLp = new AstRelease{flp, concatp->lhsp()->unlinkFrBack()};
3087 AstRelease* const newRp = new AstRelease{flp, concatp->rhsp()->unlinkFrBack()};
3088 nodep->replaceWith(newLp);
3089 newLp->addNextHere(newRp);
3090 VL_DO_DANGLING(pushDeletep(nodep), nodep);
3091 visit(newLp);
3092 visit(newRp);
3093 }
3094 }
3095
3096 void visit(AstNodeIf* nodep) override {
3097 iterateChildren(nodep);
3098 if (m_doNConst) {
3099 if (const AstConst* const constp = VN_CAST(nodep->condp(), Const)) {
3100 AstNode* keepp = nullptr;
3101 if (constp->isZero()) {
3102 UINFO(4, "IF(0,{any},{x}) => {x}: " << nodep << endl);
3103 keepp = nodep->elsesp();
3104 } else if (!m_doV || constp->isNeqZero()) { // Might be X in Verilog
3105 UINFO(4, "IF(!0,{x},{any}) => {x}: " << nodep << endl);
3106 keepp = nodep->thensp();
3107 } else {
3108 UINFO(4, "IF condition is X, retaining: " << nodep << endl);
3109 return;
3110 }
3111 if (keepp) {
3112 keepp->unlinkFrBackWithNext();
3113 nodep->replaceWith(keepp);
3114 } else {
3115 nodep->unlinkFrBack();
3116 }
3117 VL_DO_DANGLING(pushDeletep(nodep), nodep);
3118 } else if (!AstNode::afterCommentp(nodep->thensp())
3119 && !AstNode::afterCommentp(nodep->elsesp())) {
3120 if (!nodep->condp()->isPure()) {
3121 // Condition has side effect - leave - perhaps in
3122 // future simplify to remove all but side effect terms
3123 } else {
3124 // Empty block, remove it
3125 VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep);
3126 }
3127 } else if (!AstNode::afterCommentp(nodep->thensp())) {
3128 UINFO(4, "IF({x}) nullptr {...} => IF(NOT{x}}: " << nodep << endl);
3129 AstNodeExpr* const condp = nodep->condp();
3130 AstNode* const elsesp = nodep->elsesp();
3131 condp->unlinkFrBackWithNext();
3132 elsesp->unlinkFrBackWithNext();
3133 if (nodep->thensp()) { // Must have been comment
3134 pushDeletep(nodep->thensp()->unlinkFrBackWithNext());
3135 }
3136 nodep->condp(new AstLogNot{condp->fileline(),
3137 condp}); // LogNot, as C++ optimization also possible
3138 nodep->addThensp(elsesp);
3139 } else if (((VN_IS(nodep->condp(), Not) && nodep->condp()->width() == 1)
3140 || VN_IS(nodep->condp(), LogNot))
3141 && nodep->thensp() && nodep->elsesp()) {
3142 UINFO(4, "IF(NOT {x}) => IF(x) swapped if/else" << nodep << endl);
3143 AstNodeExpr* const condp
3144 = VN_AS(nodep->condp(), NodeUniop)->lhsp()->unlinkFrBackWithNext();
3145 AstNode* const thensp = nodep->thensp()->unlinkFrBackWithNext();
3146 AstNode* const elsesp = nodep->elsesp()->unlinkFrBackWithNext();
3147 AstIf* const ifp = new AstIf{nodep->fileline(), condp, elsesp, thensp};
3148 ifp->isBoundsCheck(nodep->isBoundsCheck()); // Copy bounds check info
3149 ifp->branchPred(nodep->branchPred().invert());
3150 nodep->replaceWith(ifp);
3151 VL_DO_DANGLING(pushDeletep(nodep), nodep);
3152 } else if (ifSameAssign(nodep)) {
3153 UINFO(
3154 4,
3155 "IF({a}) ASSIGN({b},{c}) else ASSIGN({b},{d}) => ASSIGN({b}, {a}?{c}:{d})\n");
3156 AstNodeAssign* const thensp = VN_AS(nodep->thensp(), NodeAssign);
3157 AstNodeAssign* const elsesp = VN_AS(nodep->elsesp(), NodeAssign);
3158 thensp->unlinkFrBack();
3159 AstNodeExpr* const condp = nodep->condp()->unlinkFrBack();
3160 AstNodeExpr* const truep = thensp->rhsp()->unlinkFrBack();
3161 AstNodeExpr* const falsep = elsesp->rhsp()->unlinkFrBack();
3162 thensp->rhsp(new AstCond{truep->fileline(), condp, truep, falsep});
3163 nodep->replaceWith(thensp);
3164 VL_DO_DANGLING(pushDeletep(nodep), nodep);
3165 } else if (false // Disabled, as vpm assertions are faster
3166 // without due to short-circuiting
3167 && operandIfIf(nodep)) {
3168 UINFO(9, "IF({a}) IF({b}) => IF({a} && {b})" << endl);
3169 AstNodeIf* const lowerIfp = VN_AS(nodep->thensp(), NodeIf);
3170 AstNodeExpr* const condp = nodep->condp()->unlinkFrBack();
3171 AstNode* const lowerThensp = lowerIfp->thensp()->unlinkFrBackWithNext();
3172 AstNodeExpr* const lowerCondp = lowerIfp->condp()->unlinkFrBackWithNext();
3173 nodep->condp(new AstLogAnd{lowerIfp->fileline(), condp, lowerCondp});
3174 lowerIfp->replaceWith(lowerThensp);
3175 VL_DO_DANGLING(pushDeletep(lowerIfp), lowerIfp);
3176 } else {
3177 // Optimizations that don't reform the IF itself
3178 if (operandBoolShift(nodep->condp())) replaceBoolShift(nodep->condp());
3179 }
3180 }
3181 }
3182
3183 void visit(AstDisplay* nodep) override {
3184 // DISPLAY(SFORMAT(text1)),DISPLAY(SFORMAT(text2)) -> DISPLAY(SFORMAT(text1+text2))
3185 iterateChildren(nodep);
3186 if (stmtDisplayDisplay(nodep)) return;
3187 }
3188 bool stmtDisplayDisplay(AstDisplay* nodep) {
3189 // DISPLAY(SFORMAT(text1)),DISPLAY(SFORMAT(text2)) -> DISPLAY(SFORMAT(text1+text2))
3190 if (!m_modp) return false; // Don't optimize under single statement
3191 AstDisplay* const prevp = VN_CAST(nodep->backp(), Display);
3192 if (!prevp) return false;
3193 if (!((prevp->displayType() == nodep->displayType())
3194 || (prevp->displayType() == VDisplayType::DT_WRITE
3195 && nodep->displayType() == VDisplayType::DT_DISPLAY)
3196 || (prevp->displayType() == VDisplayType::DT_DISPLAY
3197 && nodep->displayType() == VDisplayType::DT_WRITE)))
3198 return false;
3199 if ((prevp->filep() && !nodep->filep()) || (!prevp->filep() && nodep->filep())
3200 || (prevp->filep() && nodep->filep() && !prevp->filep()->sameTree(nodep->filep())))
3201 return false;
3202 if (!prevp->fmtp() || prevp->fmtp()->nextp() || !nodep->fmtp() || nodep->fmtp()->nextp())
3203 return false;
3204 AstSFormatF* const pformatp = prevp->fmtp();
3205 if (!pformatp) return false;
3206 AstSFormatF* const nformatp = nodep->fmtp();
3207 if (!nformatp) return false;
3208 // We don't merge scopeNames as can have only one and might be different scopes (late in
3209 // process) Also rare for real code to print %m multiple times in same message
3210 if (nformatp->scopeNamep() && pformatp->scopeNamep()) return false;
3211 // We don't early merge arguments as might need to later print warnings with
3212 // right line numbers, nor scopeNames as might be different scopes (late in process)
3213 if (!m_doCpp && pformatp->exprsp()) return false;
3214 if (!m_doCpp && nformatp->exprsp()) return false;
3215 if (pformatp->exprsp() && !pformatp->exprsp()->isPureAndNext()) return false;
3216 if (nformatp->exprsp() && !nformatp->exprsp()->isPureAndNext()) return false;
3217 // Avoid huge merges
3218 static constexpr int DISPLAY_MAX_MERGE_LENGTH = 500;
3219 if (pformatp->text().length() + nformatp->text().length() > DISPLAY_MAX_MERGE_LENGTH)
3220 return false;
3221 //
3222 UINFO(9, "DISPLAY(SF({a})) DISPLAY(SF({b})) -> DISPLAY(SF({a}+{b}))" << endl);
3223 // Convert DT_DISPLAY to DT_WRITE as may allow later optimizations
3224 if (prevp->displayType() == VDisplayType::DT_DISPLAY) {
3225 prevp->displayType(VDisplayType::DT_WRITE);
3226 pformatp->text(pformatp->text() + "\n");
3227 }
3228 // We can't replace prev() as the edit tracking iterators will get confused.
3229 // So instead we edit the prev note itself.
3230 if (prevp->addNewline()) pformatp->text(pformatp->text() + "\n");
3231 pformatp->text(pformatp->text() + nformatp->text());
3232 if (!prevp->addNewline() && nodep->addNewline()) pformatp->text(pformatp->text() + "\n");
3233 if (nformatp->exprsp()) pformatp->addExprsp(nformatp->exprsp()->unlinkFrBackWithNext());
3234 if (AstScopeName* const scopeNamep = nformatp->scopeNamep()) {
3235 scopeNamep->unlinkFrBackWithNext();
3236 pformatp->scopeNamep(scopeNamep);
3237 }
3238 VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep);
3239 return true;
3240 }
3241 void visit(AstSFormatF* nodep) override {
3242 // Substitute constants into displays. The main point of this is to
3243 // simplify assertion methodologies which call functions with display's.
3244 // This eliminates a pile of wide temps, and makes the C a whole lot more readable.
3245 iterateChildren(nodep);
3246 bool anyconst = false;
3247 for (AstNode* argp = nodep->exprsp(); argp; argp = argp->nextp()) {
3248 if (VN_IS(argp, Const)) {
3249 anyconst = true;
3250 break;
3251 }
3252 }
3253 if (m_doNConst && anyconst) {
3254 // UINFO(9," Display in "<<nodep->text()<<endl);
3255 string newFormat;
3256 string fmt;
3257 bool inPct = false;
3258 AstNode* argp = nodep->exprsp();
3259 const string text = nodep->text();
3260 for (const char ch : text) {
3261 if (!inPct && ch == '%') {
3262 inPct = true;
3263 fmt = ch;
3264 } else if (inPct && (std::isdigit(ch) || ch == '.' || ch == '-')) {
3265 fmt += ch;
3266 } else if (inPct) {
3267 inPct = false;
3268 fmt += ch;
3269 switch (std::tolower(ch)) {
3270 case '%': break; // %% - just output a %
3271 case 'm': break; // %m - auto insert "name"
3272 case 'l': break; // %l - auto insert "library"
3273 case 't': // FALLTHRU
3274 case '^': // %t/%^ - don't know $timeformat so can't constify
3275 if (argp) argp = argp->nextp();
3276 break;
3277 default: // Most operators, just move to next argument
3278 if (argp) {
3279 AstNode* const nextp = argp->nextp();
3280 if (VN_IS(argp, Const)) { // Convert it
3281 const string out = VN_AS(argp, Const)->num().displayed(nodep, fmt);
3282 UINFO(9, " DispConst: " << fmt << " -> " << out << " for "
3283 << argp << endl);
3284 // fmt = out w/ replace % with %% as it must be literal.
3285 fmt = VString::quotePercent(out);
3286 VL_DO_DANGLING(pushDeletep(argp->unlinkFrBack()), argp);
3287 }
3288 argp = nextp;
3289 }
3290 break;
3291 } // switch
3292 newFormat += fmt;
3293 } else {
3294 newFormat += ch;
3295 }
3296 }
3297 if (newFormat != nodep->text()) {
3298 nodep->text(newFormat);
3299 UINFO(9, " Display out " << nodep << endl);
3300 }
3301 }
3302 if (!nodep->exprsp() && nodep->name().find('%') == string::npos && !nodep->hidden()) {
3303 // Just a simple constant string - the formatting is pointless
3304 VL_DO_DANGLING(replaceConstString(nodep, nodep->name()), nodep);
3305 }
3306 }
3307 void visit(AstNodeFTask* nodep) override {
3308 VL_RESTORER(m_underRecFunc);
3309 if (nodep->recursive()) m_underRecFunc = true;
3310 iterateChildren(nodep);
3311 }
3312
3313 void visit(AstNodeCCall* nodep) override {
3314 iterateChildren(nodep);
3315 m_hasJumpDelay = true; // As don't analyze inside tasks for timing controls
3316 }
3317 void visit(AstNodeFTaskRef* nodep) override {
3318 // Note excludes AstFuncRef as other visitor below
3319 iterateChildren(nodep);
3320 m_hasJumpDelay = true; // As don't analyze inside tasks for timing controls
3321 }
3322 void visit(AstFuncRef* nodep) override {
3323 visit(static_cast<AstNodeFTaskRef*>(nodep));
3324 if (m_params) { // Only parameters force us to do constant function call propagation
3325 replaceWithSimulation(nodep);
3326 }
3327 }
3328 void visit(AstArg* nodep) override {
3329 // replaceWithSimulation on the Arg's parent FuncRef replaces these
3330 iterateChildren(nodep);
3331 }
3332 void visit(AstWhile* nodep) override {
3333 const bool oldHasJumpDelay = m_hasJumpDelay;
3334 m_hasJumpDelay = false;
3335 { iterateChildren(nodep); }
3336 const bool thisWhileHasJumpDelay = m_hasJumpDelay;
3337 m_hasJumpDelay = thisWhileHasJumpDelay || oldHasJumpDelay;
3338 if (m_doNConst) {
3339 if (nodep->condp()->isZero()) {
3340 UINFO(4, "WHILE(0) => nop " << nodep << endl);
3341 if (nodep->precondsp()) {
3342 nodep->replaceWith(nodep->precondsp());
3343 } else {
3344 nodep->v3warn(UNUSEDLOOP,
3345 "Loop condition is always false; body will never execute");
3346 nodep->fileline()->modifyWarnOff(V3ErrorCode::UNUSEDLOOP, true);
3347 nodep->unlinkFrBack();
3348 }
3349 VL_DO_DANGLING(pushDeletep(nodep), nodep);
3350 } else if (nodep->condp()->isNeqZero()) {
3351 if (!thisWhileHasJumpDelay) {
3352 nodep->v3warn(INFINITELOOP, "Infinite loop (condition always true)");
3353 nodep->fileline()->modifyWarnOff(V3ErrorCode::INFINITELOOP,
3354 true); // Complain just once
3355 }
3356 } else if (operandBoolShift(nodep->condp())) {
3357 replaceBoolShift(nodep->condp());
3358 }
3359 }
3360 }
3361 void visit(AstInitArray* nodep) override { iterateChildren(nodep); }
3362 void visit(AstInitItem* nodep) override { iterateChildren(nodep); }
3363 void visit(AstUnbounded* nodep) override { iterateChildren(nodep); }
3364 // These are converted by V3Param. Don't constify as we don't want the
3365 // from() VARREF to disappear, if any.
3366 // If output of a presel didn't get consted, chances are V3Param didn't visit properly
3367 void visit(AstNodePreSel*) override {}
3368
3369 // Ignored, can eliminate early
3370 void visit(AstSysIgnore* nodep) override {
3371 iterateChildren(nodep);
3372 if (m_doNConst) VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep);
3373 }
3374
3375 void visit(AstStmtExpr* nodep) override {
3376 iterateChildren(nodep);
3377 if (!nodep->exprp() || VN_IS(nodep->exprp(), Const)) {
3378 VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep);
3379 return;
3380 }
3381 // TODO if there's an ExprStmt underneath just keep lower statements
3382 // (No current test case needs this)
3383 }
3384
3385 // Simplify
3386 void visit(AstBasicDType* nodep) override {
3387 iterateChildren(nodep);
3388 nodep->cvtRangeConst();
3389 }
3390
3391 //-----
3392 // Jump elimination
3393
3394 void visit(AstJumpGo* nodep) override {
3395 iterateChildren(nodep);
3396 // Jump to label where label immediately follows this JumpGo is not useful
3397 if (nodep->labelp() == VN_CAST(nodep->nextp(), JumpLabel)) {
3398 VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep);
3399 // Keep the label, might be other jumps pointing to it, gets cleaned later
3400 return;
3401 }
3402 if (m_doExpensive) {
3403 // Any non-label statements (at this statement level) can never execute
3404 while (nodep->nextp() && !VN_IS(nodep->nextp(), JumpLabel)) {
3405 pushDeletep(nodep->nextp()->unlinkFrBack());
3406 }
3407 // If last statement in a jump label we have JumpLabel(...., JumpGo)
3408 // Often caused by "return" in a Verilog function. The Go is pointless, remove.
3409 if (replaceJumpGoNext(nodep, nodep->abovep())) return;
3410 // Also optimize If with a then or else's final statement being this JumpGo
3411 // We only do single ifs... Ideally we'd look at control flow and delete any
3412 // Jumps where any following control flow point is the label
3413 if (!nodep->nextp()) {
3414 if (AstNodeIf* const aboveIfp = VN_CAST(nodep->abovep(), NodeIf)) {
3415 if (!aboveIfp->nextp()) {
3416 if (replaceJumpGoNext(nodep, aboveIfp->abovep())) return;
3417 }
3418 }
3419 }
3420 nodep->labelp()->blockp()->user4(true);
3421 }
3422 m_hasJumpDelay = true;
3423 }
3424
3425 void visit(AstJumpBlock* nodep) override {
3426 // Because JumpLabels disable many optimizations,
3427 // remove JumpLabels that are not pointed to by any AstJumpGos
3428 // Note this assumes all AstJumpGos are underneath the given label; V3Broken asserts this
3429 iterateChildren(nodep);
3430 // AstJumpGo's below here that point to this node will set user4
3431 if (m_doExpensive && !nodep->user4()) {
3432 UINFO(4, "JUMPLABEL => unused " << nodep << endl);
3433 AstNode* underp = nullptr;
3434 if (nodep->stmtsp()) underp = nodep->stmtsp()->unlinkFrBackWithNext();
3435 if (underp) {
3436 nodep->replaceWith(underp);
3437 } else {
3438 nodep->unlinkFrBack();
3439 }
3440 pushDeletep(nodep->labelp()->unlinkFrBack());
3441 VL_DO_DANGLING(pushDeletep(nodep), nodep);
3442 }
3443 }
3444
3445 //-----
3446 // Below lines are magic expressions processed by astgen
3447 // TREE_SKIP_VISIT("AstNODETYPE") # Rename normal visit to visitGen and don't iterate
3448 //-----
3449 // clang-format off
3450 // TREE_SKIP_VISIT("ArraySel");
3451 #line 3452 "V3Const__gen.cpp"
3452 #line 3449 "../V3Const.cpp"
3453 // TREE_SKIP_VISIT("CAwait");
3454 #line 3455 "V3Const__gen.cpp"
3455 #line 3450 "../V3Const.cpp"
3456
3457 //-----
3458 // "AstNODETYPE { # bracket not paren
3459 // $accessor_name, ...
3460 // # .castFoo is the test VN_IS(object,Foo)
3461 // # ,, gets replaced with a , rather than &&
3462 // }" # bracket not paren
3463 // ,"what to call"
3464 //
3465 // Where "what_to_call" is:
3466 // "function to call"
3467 // "AstREPLACEMENT_TYPE{ $accessor }"
3468 // "! # Print line number when matches, so can see operations
3469 // "NEVER" # Print error message
3470 // "DONE" # Process of matching did the transform already
3471
3472 // In the future maybe support more complicated match & replace:
3473 // ("AstOr {%a, AstAnd{AstNot{%b}, %c}} if %a.width1 if %a==%b", "AstOr{%a,%c}; %b.delete");
3474 // Lhs/rhs would be implied; for non math operations you'd need $lhsp etc.
3475
3476 // v--- * * This op done on Verilog or C+++ mode, in all non-m_doConst stages
3477 // v--- *1* These ops are always first, as we warn before replacing
3478 // v--- *C* This op is a (C)++ op, only in m_doCpp mode
3479 // v--- *V* This op is a (V)erilog op, only in m_doV mode
3480 // v--- *A* This op works on (A)ll constant children, allowed in m_doConst mode
3481 // v--- *S* This op specifies a type should use (S)hort-circuiting of its lhs op
3482
3483 // TREEOP1("AstSel{warnSelect(nodep)}", "NEVER");
3484 #line 3485 "V3Const__gen.cpp"
3485 // TREEOP functions, each return true if they matched & transformed
3486 // Generated by astgen
3487 57257 bool match_Add_0(AstAdd* nodep) {
3488 // TREEOP ("AstAdd {$lhsp.isZero, $rhsp}", "replaceWRhs(nodep)")
3489
4/4
✓ Branch 0 taken 53382 times.
✓ Branch 1 taken 3875 times.
✓ Branch 3 taken 53143 times.
✓ Branch 4 taken 239 times.
57257 if (m_doNConst && nodep->lhsp()->isZero()) {
3490
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 239 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
239 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstAdd $lhsp.isZero, $rhsp , replaceWRhs(nodep) )\n");
3491 replaceWRhs(nodep);
3492 239 return true;
3493 }
3494 return false;
3495 }
3496 // Generated by astgen
3497 57018 bool match_Add_1(AstAdd* nodep) {
3498 // TREEOP ("AstAdd {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)")
3499
3/4
✓ Branch 0 taken 53143 times.
✓ Branch 1 taken 3875 times.
✓ Branch 3 taken 53143 times.
✗ Branch 4 not taken.
57018 if (m_doNConst && nodep->rhsp()->isZero()) {
3500 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstAdd $lhsp, $rhsp.isZero , replaceWLhs(nodep) )\n");
3501 replaceWLhs(nodep);
3502 return true;
3503 }
3504 return false;
3505 }
3506 // Generated by astgen
3507 542177 bool match_And_0(AstAnd* nodep) {
3508 // TREEOP ("AstAnd {$lhsp.isZero, $rhsp, $rhsp.isPure}", "replaceZero(nodep)")
3509
5/6
✓ Branch 0 taken 538333 times.
✓ Branch 1 taken 3844 times.
✓ Branch 3 taken 530476 times.
✓ Branch 4 taken 7857 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 7857 times.
542177 if (m_doNConst && nodep->lhsp()->isZero() && nodep->rhsp()->isPure()) {
3510
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 7857 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
7857 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstAnd $lhsp.isZero, $rhsp, $rhsp.isPure , replaceZero(nodep) )\n");
3511 replaceZero(nodep);
3512 7857 return true;
3513 }
3514 return false;
3515 }
3516 // Generated by astgen
3517 534320 bool match_And_1(AstAnd* nodep) {
3518 // TREEOP ("AstAnd {$lhsp, $rhsp.isZero}", "replaceZeroChkPure(nodep,$lhsp)")
3519
3/4
✓ Branch 0 taken 530476 times.
✓ Branch 1 taken 3844 times.
✓ Branch 3 taken 530476 times.
✗ Branch 4 not taken.
534320 if (m_doNConst && nodep->rhsp()->isZero()) {
3520 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstAnd $lhsp, $rhsp.isZero , replaceZeroChkPure(nodep,$lhsp) )\n");
3521 replaceZeroChkPure(nodep,nodep->lhsp());
3522 return true;
3523 }
3524 return false;
3525 }
3526 // Generated by astgen
3527 534320 bool match_And_2(AstAnd* nodep) {
3528 // TREEOP ("AstAnd {$lhsp.isAllOnes, $rhsp}", "replaceWRhs(nodep)")
3529
4/4
✓ Branch 0 taken 530476 times.
✓ Branch 1 taken 3844 times.
✓ Branch 3 taken 530343 times.
✓ Branch 4 taken 133 times.
534320 if (m_doNConst && nodep->lhsp()->isAllOnes()) {
3530
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 133 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
133 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstAnd $lhsp.isAllOnes, $rhsp , replaceWRhs(nodep) )\n");
3531 replaceWRhs(nodep);
3532 133 return true;
3533 }
3534 return false;
3535 }
3536 // Generated by astgen
3537 534187 bool match_And_3(AstAnd* nodep) {
3538 // TREEOP ("AstAnd {$lhsp, $rhsp.isAllOnes}", "replaceWLhs(nodep)")
3539
3/4
✓ Branch 0 taken 530343 times.
✓ Branch 1 taken 3844 times.
✓ Branch 3 taken 530343 times.
✗ Branch 4 not taken.
534187 if (m_doNConst && nodep->rhsp()->isAllOnes()) {
3540 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstAnd $lhsp, $rhsp.isAllOnes , replaceWLhs(nodep) )\n");
3541 replaceWLhs(nodep);
3542 return true;
3543 }
3544 return false;
3545 }
3546 // Generated by astgen
3547 534187 bool match_And_4(AstAnd* nodep) {
3548 // TREEOPC("AstAnd {$lhsp.isOne, matchRedundantClean(nodep)}", "DONE")
3549
6/6
✓ Branch 0 taken 440343 times.
✓ Branch 1 taken 93844 times.
✓ Branch 3 taken 365032 times.
✓ Branch 4 taken 75311 times.
✓ Branch 6 taken 75292 times.
✓ Branch 7 taken 19 times.
534187 if (m_doCpp && nodep->lhsp()->isOne() && matchRedundantClean(nodep)) {
3550
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 19 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
19 UINFO(7, cvtToHex(nodep) << " TREEOPC( AstAnd $lhsp.isOne, matchRedundantClean(nodep) , DONE )\n");
3551
3552 19 return true;
3553 }
3554 return false;
3555 }
3556 // Generated by astgen
3557 534168 bool match_And_5(AstAnd* nodep) {
3558 // TREEOP ("AstAnd {operandsSame($lhsp,,$rhsp)}", "replaceWLhs(nodep)")
3559
4/4
✓ Branch 0 taken 530324 times.
✓ Branch 1 taken 3844 times.
✓ Branch 3 taken 530253 times.
✓ Branch 4 taken 71 times.
534168 if (m_doNConst && operandsSame(nodep->lhsp(),nodep->rhsp())) {
3560
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 71 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
71 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstAnd operandsSame($lhsp,,$rhsp) , replaceWLhs(nodep) )\n");
3561 replaceWLhs(nodep);
3562 71 return true;
3563 }
3564 return false;
3565 }
3566 // Generated by astgen
3567 534097 bool match_And_6(AstAnd* nodep) {
3568 // TREEOPC("AstAnd {$lhsp.castConst, $rhsp.castRedXor, matchBitOpTree(nodep)}", "DONE")
3569
3/4
✓ Branch 0 taken 440318 times.
✓ Branch 1 taken 93779 times.
✓ Branch 3 taken 6849 times.
✗ Branch 4 not taken.
540946 if (m_doCpp && VN_IS(nodep->lhsp(),Const) && VN_IS(nodep->rhsp(),RedXor) && matchBitOpTree(nodep)) {
3570 UINFO(7, cvtToHex(nodep) << " TREEOPC( AstAnd $lhsp.castConst, $rhsp.castRedXor, matchBitOpTree(nodep) , DONE )\n");
3571
3572 return true;
3573 }
3574 return false;
3575 }
3576 // Generated by astgen
3577 534097 bool match_And_7(AstAnd* nodep) {
3578 // TREEOP ("AstAnd {$lhsp.castConst,matchAndCond(nodep)}", "DONE")
3579
4/4
✓ Branch 0 taken 530253 times.
✓ Branch 1 taken 3844 times.
✓ Branch 3 taken 449415 times.
✓ Branch 4 taken 1349 times.
984861 if (m_doNConst && VN_IS(nodep->lhsp(),Const) && matchAndCond(nodep)) {
3580
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 1349 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
1349 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstAnd $lhsp.castConst,matchAndCond(nodep) , DONE )\n");
3581
3582 1349 return true;
3583 }
3584 return false;
3585 }
3586 // Generated by astgen
3587 532748 bool match_And_8(AstAnd* nodep) {
3588 // TREEOP ("AstAnd {$lhsp.castConst, $rhsp.castOr, matchMaskedOr(nodep)}", "DONE")
3589
3/4
✓ Branch 0 taken 528904 times.
✓ Branch 1 taken 3844 times.
✓ Branch 3 taken 18994 times.
✗ Branch 4 not taken.
551742 if (m_doNConst && VN_IS(nodep->lhsp(),Const) && VN_IS(nodep->rhsp(),Or) && matchMaskedOr(nodep)) {
3590 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstAnd $lhsp.castConst, $rhsp.castOr, matchMaskedOr(nodep) , DONE )\n");
3591
3592 return true;
3593 }
3594 return false;
3595 }
3596 // Generated by astgen
3597 532748 bool match_And_9(AstAnd* nodep) {
3598 // TREEOPC("AstAnd {$lhsp.castConst, matchMaskedShift(nodep)}", "DONE")
3599
4/4
✓ Branch 0 taken 438993 times.
✓ Branch 1 taken 93755 times.
✓ Branch 3 taken 405788 times.
✓ Branch 4 taken 24188 times.
962724 if (m_doCpp && VN_IS(nodep->lhsp(),Const) && matchMaskedShift(nodep)) {
3600
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 24188 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
24188 UINFO(7, cvtToHex(nodep) << " TREEOPC( AstAnd $lhsp.castConst, matchMaskedShift(nodep) , DONE )\n");
3601
3602 24188 return true;
3603 }
3604 return false;
3605 }
3606 // Generated by astgen
3607 508560 bool match_And_10(AstAnd* nodep) {
3608 // TREEOP ("AstAnd {$lhsp.castOr, $rhsp.castOr, operandAndOrSame(nodep)}", "replaceAndOr(nodep)")
3609
3/4
✓ Branch 0 taken 504716 times.
✓ Branch 1 taken 3844 times.
✓ Branch 3 taken 66 times.
✗ Branch 4 not taken.
508626 if (m_doNConst && VN_IS(nodep->lhsp(),Or) && VN_IS(nodep->rhsp(),Or) && operandAndOrSame(nodep)) {
3610 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstAnd $lhsp.castOr, $rhsp.castOr, operandAndOrSame(nodep) , replaceAndOr(nodep) )\n");
3611 replaceAndOr(nodep);
3612 return true;
3613 }
3614 return false;
3615 }
3616 // Generated by astgen
3617 508560 bool match_And_11(AstAnd* nodep) {
3618 // TREEOP ("AstAnd {operandShiftSame(nodep)}", "replaceShiftSame(nodep)")
3619
4/4
✓ Branch 0 taken 504716 times.
✓ Branch 1 taken 3844 times.
✓ Branch 3 taken 504416 times.
✓ Branch 4 taken 300 times.
508560 if (m_doNConst && operandShiftSame(nodep)) {
3620
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 300 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
300 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstAnd operandShiftSame(nodep) , replaceShiftSame(nodep) )\n");
3621 300 replaceShiftSame(nodep);
3622 300 return true;
3623 }
3624 return false;
3625 }
3626 // Generated by astgen
3627 508260 bool match_And_12(AstAnd* nodep) {
3628 // TREEOPC("AstAnd {matchBitOpTree(nodep)}", "DONE")
3629
4/4
✓ Branch 0 taken 414518 times.
✓ Branch 1 taken 93742 times.
✓ Branch 3 taken 414423 times.
✓ Branch 4 taken 95 times.
508260 if (m_doCpp && matchBitOpTree(nodep)) {
3630
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 95 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
95 UINFO(7, cvtToHex(nodep) << " TREEOPC( AstAnd matchBitOpTree(nodep) , DONE )\n");
3631
3632 95 return true;
3633 }
3634 return false;
3635 }
3636 // Generated by astgen
3637 1318044 bool match_Concat_0(AstConcat* nodep) {
3638 // TREEOPV("AstConcat{matchConcatRand(nodep)}", "DONE")
3639
3/4
✓ Branch 0 taken 1232583 times.
✓ Branch 1 taken 85461 times.
✓ Branch 3 taken 1232583 times.
✗ Branch 4 not taken.
1318044 if (m_doV && matchConcatRand(nodep)) {
3640 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstConcat matchConcatRand(nodep) , DONE )\n");
3641
3642 return true;
3643 }
3644 return false;
3645 }
3646 // Generated by astgen
3647 1318044 bool match_Concat_1(AstConcat* nodep) {
3648 // TREEOPV("AstConcat{operandConcatMove(nodep)}", "moveConcat(nodep)")
3649
4/4
✓ Branch 0 taken 1232583 times.
✓ Branch 1 taken 85461 times.
✓ Branch 2 taken 62849 times.
✓ Branch 3 taken 1169734 times.
1318044 if (m_doV && operandConcatMove(nodep)) {
3650
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 62849 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
62849 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstConcat operandConcatMove(nodep) , moveConcat(nodep) )\n");
3651 62849 moveConcat(nodep);
3652 62849 return true;
3653 }
3654 return false;
3655 }
3656 // Generated by astgen
3657 1255195 bool match_Concat_2(AstConcat* nodep) {
3658 // TREEOPV("AstConcat{$lhsp.isZero, $rhsp}", "replaceExtend(nodep, nodep->rhsp())")
3659
4/4
✓ Branch 0 taken 1169734 times.
✓ Branch 1 taken 85461 times.
✓ Branch 3 taken 1135442 times.
✓ Branch 4 taken 34292 times.
1255195 if (m_doV && nodep->lhsp()->isZero()) {
3660
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 34292 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
34292 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstConcat $lhsp.isZero, $rhsp , replaceExtend(nodep, nodep->rhsp()) )\n");
3661 34292 replaceExtend(nodep, nodep->rhsp());
3662 34292 return true;
3663 }
3664 return false;
3665 }
3666 // Generated by astgen
3667 1220903 bool match_Concat_3(AstConcat* nodep) {
3668 // TREEOPV("AstConcat{$lhsp.castSel, $rhsp.castSel, ifAdjacentSel(VN_AS($lhsp,,Sel),,VN_AS($rhsp,,Sel))}", "replaceConcatSel(nodep)")
3669
4/4
✓ Branch 0 taken 1135442 times.
✓ Branch 1 taken 85461 times.
✓ Branch 5 taken 6648 times.
✓ Branch 6 taken 2 times.
1227553 if (m_doV && VN_IS(nodep->lhsp(),Sel) && VN_IS(nodep->rhsp(),Sel) && ifAdjacentSel(VN_AS(nodep->lhsp(),Sel),VN_AS(nodep->rhsp(),Sel))) {
3670
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
2 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstConcat $lhsp.castSel, $rhsp.castSel, ifAdjacentSel(VN_AS($lhsp,,Sel),,VN_AS($rhsp,,Sel)) , replaceConcatSel(nodep) )\n");
3671 2 replaceConcatSel(nodep);
3672 2 return true;
3673 }
3674 return false;
3675 }
3676 // Generated by astgen
3677 1220901 bool match_Concat_4(AstConcat* nodep) {
3678 // TREEOPV("AstConcat{ifConcatMergeableBiop($lhsp), concatMergeable($lhsp,,$rhsp,,0)}", "replaceConcatMerge(nodep)")
3679
3/4
✓ Branch 0 taken 1135440 times.
✓ Branch 1 taken 85461 times.
✓ Branch 3 taken 8380 times.
✗ Branch 4 not taken.
1229281 if (m_doV && ifConcatMergeableBiop(nodep->lhsp()) && concatMergeable(nodep->lhsp(),nodep->rhsp(),0)) {
3680 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstConcat ifConcatMergeableBiop($lhsp), concatMergeable($lhsp,,$rhsp,,0) , replaceConcatMerge(nodep) )\n");
3681 replaceConcatMerge(nodep);
3682 return true;
3683 }
3684 return false;
3685 }
3686 // Generated by astgen
3687 1220901 bool match_Concat_5(AstConcat* nodep) {
3688 // TREEOPV("AstConcat{operandConcatSame(nodep)}", "DONE")
3689
4/4
✓ Branch 0 taken 1135440 times.
✓ Branch 1 taken 85461 times.
✓ Branch 3 taken 1135094 times.
✓ Branch 4 taken 346 times.
1220901 if (m_doV && operandConcatSame(nodep)) {
3690
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 346 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
346 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstConcat operandConcatSame(nodep) , DONE )\n");
3691
3692 346 return true;
3693 }
3694 return false;
3695 }
3696 // Generated by astgen
3697 852585 bool match_Cond_0(AstCond* nodep) {
3698 // TREEOPS("AstCond {$condp.isZero}", "replaceWIteratedThs(nodep)")
3699
4/4
✓ Branch 0 taken 773767 times.
✓ Branch 1 taken 78818 times.
✓ Branch 3 taken 769891 times.
✓ Branch 4 taken 3876 times.
852585 if (m_doNConst && nodep->condp()->isZero()) {
3700
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 3876 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
3876 UINFO(7, cvtToHex(nodep) << " TREEOPS( AstCond $condp.isZero , replaceWIteratedThs(nodep) )\n");
3701 3876 replaceWIteratedThs(nodep);
3702 3876 return true;
3703 }
3704 return false;
3705 }
3706 // Generated by astgen
3707 848709 bool match_Cond_1(AstCond* nodep) {
3708 // TREEOPS("AstCond {$condp.isNeqZero}", "replaceWIteratedRhs(nodep)")
3709
4/4
✓ Branch 0 taken 769891 times.
✓ Branch 1 taken 78818 times.
✓ Branch 3 taken 755093 times.
✓ Branch 4 taken 14798 times.
848709 if (m_doNConst && nodep->condp()->isNeqZero()) {
3710
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 14798 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
14798 UINFO(7, cvtToHex(nodep) << " TREEOPS( AstCond $condp.isNeqZero , replaceWIteratedRhs(nodep) )\n");
3711 14798 replaceWIteratedRhs(nodep);
3712 14798 return true;
3713 }
3714 return false;
3715 }
3716 // Generated by astgen
3717 831411 bool match_Cond_2(AstCond* nodep) {
3718 // TREEOP ("AstCond{$condp.castNot, $thenp, $elsep}", "AstCond{$condp->castNot()->lhsp(), $elsep, $thenp}")
3719
2/2
✓ Branch 0 taken 752722 times.
✓ Branch 1 taken 78689 times.
831411 if (m_doNConst && VN_IS(nodep->condp(),Not)) {
3720
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 3982 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
3982 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstCond $condp.castNot, $thenp, $elsep , AstCond $condp->castNot()->lhsp(), $elsep, $thenp )\n");
3721 AstNodeExpr* arg1p = VN_CAST(nodep->condp(),Not)->lhsp()->unlinkFrBack();
3722 AstNodeExpr* arg2p = nodep->elsep()->unlinkFrBack();
3723 AstNodeExpr* arg3p = nodep->thenp()->unlinkFrBack();
3724 3982 AstNodeExpr* newp = new AstCond(nodep->fileline(), arg1p, arg2p, arg3p);
3725 3982 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
3726 3982 return true;
3727 }
3728 return false;
3729 }
3730 // Generated by astgen
3731 bool match_CvtPackString_0(AstCvtPackString* nodep) {
3732 // TREEOPA("AstCvtPackString{$lhsp.castConst}", "replaceConstString(nodep, VN_AS(nodep->lhsp(), Const)->num().toString())")
3733 if (VN_IS(nodep->lhsp(),Const)) {
3734 UINFO(7, cvtToHex(nodep) << " TREEOPA( AstCvtPackString $lhsp.castConst , replaceConstString(nodep, VN_AS(nodep->lhsp(), Const)->num().toString()) )\n");
3735 replaceConstString(nodep, VN_AS(nodep->lhsp(), Const)->num().toString());
3736 return true;
3737 }
3738 return false;
3739 }
3740 // Generated by astgen
3741 bool match_Div_0(AstDiv* nodep) {
3742 // TREEOP ("AstDiv {$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)")
3743 if (m_doNConst && nodep->lhsp()->isZero()) {
3744 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstDiv $lhsp.isZero, $rhsp , replaceZeroChkPure(nodep,$rhsp) )\n");
3745 replaceZeroChkPure(nodep,nodep->rhsp());
3746 return true;
3747 }
3748 return false;
3749 }
3750 // Generated by astgen
3751 bool match_Div_1(AstDiv* nodep) {
3752 // TREEOP ("AstDiv {$lhsp, $rhsp.isOne}", "replaceWLhs(nodep)")
3753 if (m_doNConst && nodep->rhsp()->isOne()) {
3754 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstDiv $lhsp, $rhsp.isOne , replaceWLhs(nodep) )\n");
3755 replaceWLhs(nodep);
3756 return true;
3757 }
3758 return false;
3759 }
3760 // Generated by astgen
3761 bool match_Div_2(AstDiv* nodep) {
3762 // TREEOP ("AstDiv {$lhsp, operandIsPowTwo($rhsp)}", "replaceDivShift(nodep)")
3763 if (m_doNConst && operandIsPowTwo(nodep->rhsp())) {
3764 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstDiv $lhsp, operandIsPowTwo($rhsp) , replaceDivShift(nodep) )\n");
3765 replaceDivShift(nodep);
3766 return true;
3767 }
3768 return false;
3769 }
3770 // Generated by astgen
3771 bool match_Div_3(AstDiv* nodep) {
3772 // TREEOP ("AstDiv {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)")
3773 if (m_doNConst && operandsSame(nodep->lhsp(),nodep->rhsp())) {
3774 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstDiv operandsSame($lhsp,,$rhsp) , replaceNum(nodep,1) )\n");
3775 replaceNum(nodep,1);
3776 return true;
3777 }
3778 return false;
3779 }
3780 // Generated by astgen
3781 bool match_DivS_0(AstDivS* nodep) {
3782 // TREEOP ("AstDivS {$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)")
3783 if (m_doNConst && nodep->lhsp()->isZero()) {
3784 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstDivS $lhsp.isZero, $rhsp , replaceZeroChkPure(nodep,$rhsp) )\n");
3785 replaceZeroChkPure(nodep,nodep->rhsp());
3786 return true;
3787 }
3788 return false;
3789 }
3790 // Generated by astgen
3791 bool match_DivS_1(AstDivS* nodep) {
3792 // TREEOP ("AstDivS {$lhsp, $rhsp.isOne}", "replaceWLhs(nodep)")
3793 if (m_doNConst && nodep->rhsp()->isOne()) {
3794 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstDivS $lhsp, $rhsp.isOne , replaceWLhs(nodep) )\n");
3795 replaceWLhs(nodep);
3796 return true;
3797 }
3798 return false;
3799 }
3800 // Generated by astgen
3801 bool match_DivS_2(AstDivS* nodep) {
3802 // TREEOP ("AstDivS {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)")
3803 if (m_doNConst && operandsSame(nodep->lhsp(),nodep->rhsp())) {
3804 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstDivS operandsSame($lhsp,,$rhsp) , replaceNum(nodep,1) )\n");
3805 replaceNum(nodep,1);
3806 return true;
3807 }
3808 return false;
3809 }
3810 // Generated by astgen
3811 60139 bool match_Eq_0(AstEq* nodep) {
3812 // TREEOPV("AstEq {$rhsp.castExtend,operandBiExtendConstShrink(nodep)}", "DONE")
3813
4/4
✓ Branch 0 taken 37875 times.
✓ Branch 1 taken 22264 times.
✓ Branch 3 taken 11528 times.
✓ Branch 4 taken 83 times.
71750 if (m_doV && VN_IS(nodep->rhsp(),Extend) && operandBiExtendConstShrink(nodep)) {
3814
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 83 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
83 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstEq $rhsp.castExtend,operandBiExtendConstShrink(nodep) , DONE )\n");
3815
3816 83 return true;
3817 }
3818 return false;
3819 }
3820 // Generated by astgen
3821 60056 bool match_Eq_1(AstEq* nodep) {
3822 // TREEOPV("AstEq {$rhsp.castExtend,operandBiExtendConstOver(nodep)}", "replaceZero(nodep)")
3823
4/4
✓ Branch 0 taken 37792 times.
✓ Branch 1 taken 22264 times.
✓ Branch 3 taken 11304 times.
✓ Branch 4 taken 224 times.
71584 if (m_doV && VN_IS(nodep->rhsp(),Extend) && operandBiExtendConstOver(nodep)) {
3824
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 224 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
224 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstEq $rhsp.castExtend,operandBiExtendConstOver(nodep) , replaceZero(nodep) )\n");
3825 replaceZero(nodep);
3826 224 return true;
3827 }
3828 return false;
3829 }
3830 // Generated by astgen
3831 59832 bool match_Eq_2(AstEq* nodep) {
3832 // TREEOP ("AstEq {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)")
3833
4/4
✓ Branch 0 taken 55931 times.
✓ Branch 1 taken 3901 times.
✓ Branch 3 taken 55860 times.
✓ Branch 4 taken 71 times.
59832 if (m_doNConst && operandsSame(nodep->lhsp(),nodep->rhsp())) {
3834
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 71 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
71 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstEq operandsSame($lhsp,,$rhsp) , replaceNum(nodep,1) )\n");
3835 71 replaceNum(nodep,1);
3836 71 return true;
3837 }
3838 return false;
3839 }
3840 // Generated by astgen
3841 59761 bool match_Eq_3(AstEq* nodep) {
3842 // TREEOPV("AstEq {$rhsp.width1, $lhsp.isZero, $rhsp}", "AstNot{$rhsp}")
3843
4/4
✓ Branch 0 taken 37497 times.
✓ Branch 1 taken 22264 times.
✓ Branch 3 taken 1494 times.
✓ Branch 4 taken 48 times.
61303 if (m_doV && nodep->rhsp()->width1() && nodep->lhsp()->isZero()) {
3844
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 48 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
48 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstEq $rhsp.width1, $lhsp.isZero, $rhsp , AstNot $rhsp )\n");
3845 AstNodeExpr* arg1p = nodep->rhsp()->unlinkFrBack();
3846
1/2
✓ Branch 2 taken 48 times.
✗ Branch 3 not taken.
48 AstNodeExpr* newp = new AstNot(nodep->fileline(), arg1p);
3847 48 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
3848 48 return true;
3849 }
3850 return false;
3851 }
3852 // Generated by astgen
3853 59713 bool match_Eq_4(AstEq* nodep) {
3854 // TREEOPV("AstEq {$lhsp.width1, $lhsp, $rhsp.isZero}", "AstNot{$lhsp}")
3855
3/4
✓ Branch 0 taken 37449 times.
✓ Branch 1 taken 22264 times.
✓ Branch 3 taken 1494 times.
✗ Branch 4 not taken.
61207 if (m_doV && nodep->lhsp()->width1() && nodep->rhsp()->isZero()) {
3856 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstEq $lhsp.width1, $lhsp, $rhsp.isZero , AstNot $lhsp )\n");
3857 AstNodeExpr* arg1p = nodep->lhsp()->unlinkFrBack();
3858 AstNodeExpr* newp = new AstNot(nodep->fileline(), arg1p);
3859 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
3860 return true;
3861 }
3862 return false;
3863 }
3864 // Generated by astgen
3865 59713 bool match_Eq_5(AstEq* nodep) {
3866 // TREEOPV("AstEq {$rhsp.width1, $lhsp.isAllOnes, $rhsp}", "replaceWRhs(nodep)")
3867
4/4
✓ Branch 0 taken 37449 times.
✓ Branch 1 taken 22264 times.
✓ Branch 3 taken 1464 times.
✓ Branch 4 taken 30 times.
61207 if (m_doV && nodep->rhsp()->width1() && nodep->lhsp()->isAllOnes()) {
3868
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 30 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
30 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstEq $rhsp.width1, $lhsp.isAllOnes, $rhsp , replaceWRhs(nodep) )\n");
3869 replaceWRhs(nodep);
3870 30 return true;
3871 }
3872 return false;
3873 }
3874 // Generated by astgen
3875 59683 bool match_Eq_6(AstEq* nodep) {
3876 // TREEOPV("AstEq {$lhsp.width1, $lhsp, $rhsp.isAllOnes}", "replaceWLhs(nodep)")
3877
3/4
✓ Branch 0 taken 37419 times.
✓ Branch 1 taken 22264 times.
✓ Branch 3 taken 1464 times.
✗ Branch 4 not taken.
61147 if (m_doV && nodep->lhsp()->width1() && nodep->rhsp()->isAllOnes()) {
3878 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstEq $lhsp.width1, $lhsp, $rhsp.isAllOnes , replaceWLhs(nodep) )\n");
3879 replaceWLhs(nodep);
3880 return true;
3881 }
3882 return false;
3883 }
3884 // Generated by astgen
3885 bool match_EqCase_0(AstEqCase* nodep) {
3886 // TREEOP ("AstEqCase {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)")
3887 if (m_doNConst && operandsSame(nodep->lhsp(),nodep->rhsp())) {
3888 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstEqCase operandsSame($lhsp,,$rhsp) , replaceNum(nodep,1) )\n");
3889 replaceNum(nodep,1);
3890 return true;
3891 }
3892 return false;
3893 }
3894 // Generated by astgen
3895 bool match_EqD_0(AstEqD* nodep) {
3896 // TREEOP ("AstEqD {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)")
3897 if (m_doNConst && operandsSame(nodep->lhsp(),nodep->rhsp())) {
3898 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstEqD operandsSame($lhsp,,$rhsp) , replaceNum(nodep,1) )\n");
3899 replaceNum(nodep,1);
3900 return true;
3901 }
3902 return false;
3903 }
3904 // Generated by astgen
3905 bool match_EqN_0(AstEqN* nodep) {
3906 // TREEOP ("AstEqN {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)")
3907 if (m_doNConst && operandsSame(nodep->lhsp(),nodep->rhsp())) {
3908 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstEqN operandsSame($lhsp,,$rhsp) , replaceNum(nodep,1) )\n");
3909 replaceNum(nodep,1);
3910 return true;
3911 }
3912 return false;
3913 }
3914 // Generated by astgen
3915 bool match_EqWild_0(AstEqWild* nodep) {
3916 // TREEOP ("AstEqWild {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)")
3917 if (m_doNConst && operandsSame(nodep->lhsp(),nodep->rhsp())) {
3918 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstEqWild operandsSame($lhsp,,$rhsp) , replaceNum(nodep,1) )\n");
3919 replaceNum(nodep,1);
3920 return true;
3921 }
3922 return false;
3923 }
3924 // Generated by astgen
3925 1486080 bool match_Extend_0(AstExtend* nodep) {
3926 // TREEOPV("AstExtend{operandsSameWidth(nodep,,$lhsp)}", "replaceWLhs(nodep)")
3927
3/4
✓ Branch 0 taken 1344749 times.
✓ Branch 1 taken 141331 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1344749 times.
2830829 if (m_doV && operandsSameWidth(nodep,nodep->lhsp())) {
3928 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstExtend operandsSameWidth(nodep,,$lhsp) , replaceWLhs(nodep) )\n");
3929 replaceWLhs(nodep);
3930 return true;
3931 }
3932 return false;
3933 }
3934 // Generated by astgen
3935 1486080 bool match_Extend_1(AstExtend* nodep) {
3936 // TREEOPV("AstExtend{$lhsp.castExtend}", "replaceExtend(nodep, VN_AS(nodep->lhsp(), Extend)->lhsp())")
3937
2/2
✓ Branch 0 taken 1344749 times.
✓ Branch 1 taken 141331 times.
1486080 if (m_doV && VN_IS(nodep->lhsp(),Extend)) {
3938
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 4951 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
4951 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstExtend $lhsp.castExtend , replaceExtend(nodep, VN_AS(nodep->lhsp(), Extend)->lhsp()) )\n");
3939 4951 replaceExtend(nodep, VN_AS(nodep->lhsp(), Extend)->lhsp());
3940 4951 return true;
3941 }
3942 return false;
3943 }
3944 // Generated by astgen
3945 243920 bool match_ExtendS_0(AstExtendS* nodep) {
3946 // TREEOPV("AstExtendS{$lhsp.castExtendS}", "replaceExtend(nodep, VN_AS(nodep->lhsp(), ExtendS)->lhsp())")
3947
2/2
✓ Branch 0 taken 184882 times.
✓ Branch 1 taken 59038 times.
243920 if (m_doV && VN_IS(nodep->lhsp(),ExtendS)) {
3948
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 138 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
138 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstExtendS $lhsp.castExtendS , replaceExtend(nodep, VN_AS(nodep->lhsp(), ExtendS)->lhsp()) )\n");
3949 138 replaceExtend(nodep, VN_AS(nodep->lhsp(), ExtendS)->lhsp());
3950 138 return true;
3951 }
3952 return false;
3953 }
3954 // Generated by astgen
3955 42182 bool match_Gt_0(AstGt* nodep) {
3956 // TREEOP ("AstGt {!$lhsp.castConst,$rhsp.castConst}", "AstLt {$rhsp,$lhsp}")
3957
2/2
✓ Branch 0 taken 38619 times.
✓ Branch 1 taken 3563 times.
42182 if (m_doNConst && !VN_IS(nodep->lhsp(),Const) && VN_IS(nodep->rhsp(),Const)) {
3958
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 2410 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
2410 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstGt !$lhsp.castConst,$rhsp.castConst , AstLt $rhsp,$lhsp )\n");
3959 AstNodeExpr* arg1p = nodep->rhsp()->unlinkFrBack();
3960 AstNodeExpr* arg2p = nodep->lhsp()->unlinkFrBack();
3961
1/2
✓ Branch 2 taken 2410 times.
✗ Branch 3 not taken.
2410 AstNodeExpr* newp = new AstLt(nodep->fileline(), arg1p, arg2p);
3962 2410 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
3963 2410 return true;
3964 }
3965 return false;
3966 }
3967 // Generated by astgen
3968 42664 bool match_Gt_1(AstGt* nodep) {
3969 // TREEOP1("AstGt {$lhsp.isZero, $rhsp}", "replaceNumSigned(nodep,0)")
3970
4/4
✓ Branch 0 taken 39055 times.
✓ Branch 1 taken 3609 times.
✓ Branch 3 taken 38899 times.
✓ Branch 4 taken 156 times.
42664 if (m_doNConst && nodep->lhsp()->isZero()) {
3971
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 156 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
156 UINFO(7, cvtToHex(nodep) << " TREEOP1( AstGt $lhsp.isZero, $rhsp , replaceNumSigned(nodep,0) )\n");
3972 156 replaceNumSigned(nodep,0);
3973 156 return true;
3974 }
3975 return false;
3976 }
3977 // Generated by astgen
3978 42699 bool match_Gt_2(AstGt* nodep) {
3979 // TREEOP1("AstGt {$lhsp, $rhsp.isAllOnes, $lhsp->width()==$rhsp->width()}", "replaceNumLimited(nodep,0)")
3980
5/6
✓ Branch 0 taken 39090 times.
✓ Branch 1 taken 3609 times.
✓ Branch 3 taken 39055 times.
✓ Branch 4 taken 35 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 35 times.
42734 if (m_doNConst && nodep->rhsp()->isAllOnes() && nodep->lhsp()->width()==nodep->rhsp()->width()) {
3981
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 35 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
35 UINFO(7, cvtToHex(nodep) << " TREEOP1( AstGt $lhsp, $rhsp.isAllOnes, $lhsp->width()==$rhsp->width() , replaceNumLimited(nodep,0) )\n");
3982 35 replaceNumLimited(nodep,0);
3983 35 return true;
3984 }
3985 return false;
3986 }
3987 // Generated by astgen
3988 39772 bool match_Gt_3(AstGt* nodep) {
3989 // TREEOPV("AstGt {$rhsp.castExtend,operandBiExtendConstShrink(nodep)}", "DONE")
3990
4/4
✓ Branch 0 taken 32230 times.
✓ Branch 1 taken 7542 times.
✓ Branch 3 taken 11284 times.
✓ Branch 4 taken 30 times.
51086 if (m_doV && VN_IS(nodep->rhsp(),Extend) && operandBiExtendConstShrink(nodep)) {
3991
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 30 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
30 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstGt $rhsp.castExtend,operandBiExtendConstShrink(nodep) , DONE )\n");
3992
3993 30 return true;
3994 }
3995 return false;
3996 }
3997 // Generated by astgen
3998 39742 bool match_Gt_4(AstGt* nodep) {
3999 // TREEOPV("AstGt {$rhsp.castExtend,operandBiExtendConstOver(nodep)}", "replaceNum(nodep,1)")
4000
4/4
✓ Branch 0 taken 32200 times.
✓ Branch 1 taken 7542 times.
✓ Branch 3 taken 11038 times.
✓ Branch 4 taken 246 times.
51026 if (m_doV && VN_IS(nodep->rhsp(),Extend) && operandBiExtendConstOver(nodep)) {
4001
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 246 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
246 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstGt $rhsp.castExtend,operandBiExtendConstOver(nodep) , replaceNum(nodep,1) )\n");
4002 246 replaceNum(nodep,1);
4003 246 return true;
4004 }
4005 return false;
4006 }
4007 // Generated by astgen
4008 39496 bool match_Gt_5(AstGt* nodep) {
4009 // TREEOP ("AstGt {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)")
4010
4/4
✓ Branch 0 taken 35933 times.
✓ Branch 1 taken 3563 times.
✓ Branch 3 taken 35899 times.
✓ Branch 4 taken 34 times.
39496 if (m_doNConst && operandsSame(nodep->lhsp(),nodep->rhsp())) {
4011
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 34 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
34 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstGt operandsSame($lhsp,,$rhsp) , replaceZero(nodep) )\n");
4012 replaceZero(nodep);
4013 34 return true;
4014 }
4015 return false;
4016 }
4017 // Generated by astgen
4018 39462 bool match_Gt_6(AstGt* nodep) {
4019 // TREEOPV("AstGt {$lhsp.width1, $lhsp, $rhsp.isZero}", "replaceWLhs(nodep)")
4020
3/4
✓ Branch 0 taken 31921 times.
✓ Branch 1 taken 7541 times.
✓ Branch 3 taken 1792 times.
✗ Branch 4 not taken.
41254 if (m_doV && nodep->lhsp()->width1() && nodep->rhsp()->isZero()) {
4021 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstGt $lhsp.width1, $lhsp, $rhsp.isZero , replaceWLhs(nodep) )\n");
4022 replaceWLhs(nodep);
4023 return true;
4024 }
4025 return false;
4026 }
4027 // Generated by astgen
4028 bool match_GtD_0(AstGtD* nodep) {
4029 // TREEOP ("AstGtD {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)")
4030 if (m_doNConst && operandsSame(nodep->lhsp(),nodep->rhsp())) {
4031 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstGtD operandsSame($lhsp,,$rhsp) , replaceZero(nodep) )\n");
4032 replaceZero(nodep);
4033 return true;
4034 }
4035 return false;
4036 }
4037 // Generated by astgen
4038 bool match_GtN_0(AstGtN* nodep) {
4039 // TREEOP ("AstGtN {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)")
4040 if (m_doNConst && operandsSame(nodep->lhsp(),nodep->rhsp())) {
4041 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstGtN operandsSame($lhsp,,$rhsp) , replaceZero(nodep) )\n");
4042 replaceZero(nodep);
4043 return true;
4044 }
4045 return false;
4046 }
4047 // Generated by astgen
4048 4296 bool match_GtS_0(AstGtS* nodep) {
4049 // TREEOP ("AstGtS {!$lhsp.castConst,$rhsp.castConst}", "AstLtS {$rhsp,$lhsp}")
4050
2/2
✓ Branch 0 taken 3943 times.
✓ Branch 1 taken 353 times.
4296 if (m_doNConst && !VN_IS(nodep->lhsp(),Const) && VN_IS(nodep->rhsp(),Const)) {
4051
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 30 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
30 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstGtS !$lhsp.castConst,$rhsp.castConst , AstLtS $rhsp,$lhsp )\n");
4052 AstNodeExpr* arg1p = nodep->rhsp()->unlinkFrBack();
4053 AstNodeExpr* arg2p = nodep->lhsp()->unlinkFrBack();
4054
1/2
✓ Branch 2 taken 30 times.
✗ Branch 3 not taken.
30 AstNodeExpr* newp = new AstLtS(nodep->fileline(), arg1p, arg2p);
4055 30 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
4056 30 return true;
4057 }
4058 return false;
4059 }
4060 // Generated by astgen
4061 4266 bool match_GtS_1(AstGtS* nodep) {
4062 // TREEOP ("AstGtS {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)")
4063
4/4
✓ Branch 0 taken 3913 times.
✓ Branch 1 taken 353 times.
✓ Branch 3 taken 3886 times.
✓ Branch 4 taken 27 times.
4266 if (m_doNConst && operandsSame(nodep->lhsp(),nodep->rhsp())) {
4064
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 27 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
27 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstGtS operandsSame($lhsp,,$rhsp) , replaceZero(nodep) )\n");
4065 replaceZero(nodep);
4066 27 return true;
4067 }
4068 return false;
4069 }
4070 // Generated by astgen
4071 43057 bool match_Gte_0(AstGte* nodep) {
4072 // TREEOP ("AstGte {!$lhsp.castConst,$rhsp.castConst}", "AstLte {$rhsp,$lhsp}")
4073
2/2
✓ Branch 0 taken 39448 times.
✓ Branch 1 taken 3609 times.
43057 if (m_doNConst && !VN_IS(nodep->lhsp(),Const) && VN_IS(nodep->rhsp(),Const)) {
4074
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 419 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
419 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstGte !$lhsp.castConst,$rhsp.castConst , AstLte $rhsp,$lhsp )\n");
4075 AstNodeExpr* arg1p = nodep->rhsp()->unlinkFrBack();
4076 AstNodeExpr* arg2p = nodep->lhsp()->unlinkFrBack();
4077
1/2
✓ Branch 2 taken 419 times.
✗ Branch 3 not taken.
419 AstNodeExpr* newp = new AstLte(nodep->fileline(), arg1p, arg2p);
4078 419 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
4079 419 return true;
4080 }
4081 return false;
4082 }
4083 // Generated by astgen
4084 136897 bool match_Gte_1(AstGte* nodep) {
4085 // TREEOP1("AstGte {$lhsp, $rhsp.isZero}", "replaceNumSigned(nodep,1)")
4086
4/4
✓ Branch 0 taken 133253 times.
✓ Branch 1 taken 3644 times.
✓ Branch 3 taken 83744 times.
✓ Branch 4 taken 49509 times.
136897 if (m_doNConst && nodep->rhsp()->isZero()) {
4087
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 49509 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
49509 UINFO(7, cvtToHex(nodep) << " TREEOP1( AstGte $lhsp, $rhsp.isZero , replaceNumSigned(nodep,1) )\n");
4088 49509 replaceNumSigned(nodep,1);
4089 49509 return true;
4090 }
4091 return false;
4092 }
4093 // Generated by astgen
4094 146655 bool match_Gte_2(AstGte* nodep) {
4095 // TREEOP1("AstGte {$lhsp.isAllOnes, $rhsp, $lhsp->width()==$rhsp->width()}", "replaceNumLimited(nodep,1)")
4096
5/6
✓ Branch 0 taken 143011 times.
✓ Branch 1 taken 3644 times.
✓ Branch 3 taken 133253 times.
✓ Branch 4 taken 9758 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 9758 times.
156413 if (m_doNConst && nodep->lhsp()->isAllOnes() && nodep->lhsp()->width()==nodep->rhsp()->width()) {
4097
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 9758 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
9758 UINFO(7, cvtToHex(nodep) << " TREEOP1( AstGte $lhsp.isAllOnes, $rhsp, $lhsp->width()==$rhsp->width() , replaceNumLimited(nodep,1) )\n");
4098 9758 replaceNumLimited(nodep,1);
4099 9758 return true;
4100 }
4101 return false;
4102 }
4103 // Generated by astgen
4104 42638 bool match_Gte_3(AstGte* nodep) {
4105 // TREEOPV("AstGte {$rhsp.castExtend,operandBiExtendConstShrink(nodep)}", "DONE")
4106
4/4
✓ Branch 0 taken 34636 times.
✓ Branch 1 taken 8002 times.
✓ Branch 3 taken 11215 times.
✓ Branch 4 taken 116 times.
53969 if (m_doV && VN_IS(nodep->rhsp(),Extend) && operandBiExtendConstShrink(nodep)) {
4107
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 116 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
116 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstGte $rhsp.castExtend,operandBiExtendConstShrink(nodep) , DONE )\n");
4108
4109 116 return true;
4110 }
4111 return false;
4112 }
4113 // Generated by astgen
4114 42522 bool match_Gte_4(AstGte* nodep) {
4115 // TREEOPV("AstGte {$rhsp.castExtend,operandBiExtendConstOver(nodep)}", "replaceNum(nodep,1)")
4116
4/4
✓ Branch 0 taken 34520 times.
✓ Branch 1 taken 8002 times.
✓ Branch 3 taken 10983 times.
✓ Branch 4 taken 232 times.
53737 if (m_doV && VN_IS(nodep->rhsp(),Extend) && operandBiExtendConstOver(nodep)) {
4117
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 232 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
232 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstGte $rhsp.castExtend,operandBiExtendConstOver(nodep) , replaceNum(nodep,1) )\n");
4118 232 replaceNum(nodep,1);
4119 232 return true;
4120 }
4121 return false;
4122 }
4123 // Generated by astgen
4124 42290 bool match_Gte_5(AstGte* nodep) {
4125 // TREEOP ("AstGte {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)")
4126
4/4
✓ Branch 0 taken 38681 times.
✓ Branch 1 taken 3609 times.
✓ Branch 3 taken 38654 times.
✓ Branch 4 taken 27 times.
42290 if (m_doNConst && operandsSame(nodep->lhsp(),nodep->rhsp())) {
4127
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 27 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
27 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstGte operandsSame($lhsp,,$rhsp) , replaceNum(nodep,1) )\n");
4128 27 replaceNum(nodep,1);
4129 27 return true;
4130 }
4131 return false;
4132 }
4133 // Generated by astgen
4134 bool match_GteD_0(AstGteD* nodep) {
4135 // TREEOP ("AstGteD {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)")
4136 if (m_doNConst && operandsSame(nodep->lhsp(),nodep->rhsp())) {
4137 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstGteD operandsSame($lhsp,,$rhsp) , replaceNum(nodep,1) )\n");
4138 replaceNum(nodep,1);
4139 return true;
4140 }
4141 return false;
4142 }
4143 // Generated by astgen
4144 bool match_GteN_0(AstGteN* nodep) {
4145 // TREEOP ("AstGteN {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)")
4146 if (m_doNConst && operandsSame(nodep->lhsp(),nodep->rhsp())) {
4147 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstGteN operandsSame($lhsp,,$rhsp) , replaceNum(nodep,1) )\n");
4148 replaceNum(nodep,1);
4149 return true;
4150 }
4151 return false;
4152 }
4153 // Generated by astgen
4154 3661 bool match_GteS_0(AstGteS* nodep) {
4155 // TREEOP ("AstGteS {!$lhsp.castConst,$rhsp.castConst}", "AstLteS{$rhsp,$lhsp}")
4156
2/2
✓ Branch 0 taken 3335 times.
✓ Branch 1 taken 326 times.
3661 if (m_doNConst && !VN_IS(nodep->lhsp(),Const) && VN_IS(nodep->rhsp(),Const)) {
4157
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
24 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstGteS !$lhsp.castConst,$rhsp.castConst , AstLteS $rhsp,$lhsp )\n");
4158 AstNodeExpr* arg1p = nodep->rhsp()->unlinkFrBack();
4159 AstNodeExpr* arg2p = nodep->lhsp()->unlinkFrBack();
4160
1/2
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
24 AstNodeExpr* newp = new AstLteS(nodep->fileline(), arg1p, arg2p);
4161 24 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
4162 24 return true;
4163 }
4164 return false;
4165 }
4166 // Generated by astgen
4167 3637 bool match_GteS_1(AstGteS* nodep) {
4168 // TREEOP ("AstGteS {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)")
4169
4/4
✓ Branch 0 taken 3311 times.
✓ Branch 1 taken 326 times.
✓ Branch 3 taken 3293 times.
✓ Branch 4 taken 18 times.
3637 if (m_doNConst && operandsSame(nodep->lhsp(),nodep->rhsp())) {
4170
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 18 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
18 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstGteS operandsSame($lhsp,,$rhsp) , replaceNum(nodep,1) )\n");
4171 18 replaceNum(nodep,1);
4172 18 return true;
4173 }
4174 return false;
4175 }
4176 // Generated by astgen
4177 bool match_IsUnbounded_0(AstIsUnbounded* nodep) {
4178 // TREEOPV("AstIsUnbounded{$lhsp.castUnbounded}", "replaceNum(nodep, 1)")
4179 if (m_doV && VN_IS(nodep->lhsp(),Unbounded)) {
4180 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstIsUnbounded $lhsp.castUnbounded , replaceNum(nodep, 1) )\n");
4181 replaceNum(nodep, 1);
4182 return true;
4183 }
4184 return false;
4185 }
4186 // Generated by astgen
4187 8542 bool match_LogAnd_0(AstLogAnd* nodep) {
4188 // TREEOPS("AstLogAnd {$lhsp.isZero}", "replaceZero(nodep)")
4189
4/4
✓ Branch 0 taken 4615 times.
✓ Branch 1 taken 3927 times.
✓ Branch 3 taken 4498 times.
✓ Branch 4 taken 117 times.
8542 if (m_doNConst && nodep->lhsp()->isZero()) {
4190
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 117 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
117 UINFO(7, cvtToHex(nodep) << " TREEOPS( AstLogAnd $lhsp.isZero , replaceZero(nodep) )\n");
4191 replaceZero(nodep);
4192 117 return true;
4193 }
4194 return false;
4195 }
4196 // Generated by astgen
4197 8090 bool match_LogAnd_1(AstLogAnd* nodep) {
4198 // TREEOP ("AstLogAnd{$lhsp.isZero, $rhsp}", "replaceZero(nodep)")
4199
3/4
✓ Branch 0 taken 4213 times.
✓ Branch 1 taken 3877 times.
✓ Branch 3 taken 4213 times.
✗ Branch 4 not taken.
8090 if (m_doNConst && nodep->lhsp()->isZero()) {
4200 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstLogAnd $lhsp.isZero, $rhsp , replaceZero(nodep) )\n");
4201 replaceZero(nodep);
4202 return true;
4203 }
4204 return false;
4205 }
4206 // Generated by astgen
4207 8090 bool match_LogAnd_2(AstLogAnd* nodep) {
4208 // TREEOP ("AstLogAnd{$lhsp, $rhsp.isZero}", "replaceZeroChkPure(nodep,$lhsp)")
4209
4/4
✓ Branch 0 taken 4213 times.
✓ Branch 1 taken 3877 times.
✓ Branch 3 taken 4167 times.
✓ Branch 4 taken 46 times.
8090 if (m_doNConst && nodep->rhsp()->isZero()) {
4210
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 46 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
46 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstLogAnd $lhsp, $rhsp.isZero , replaceZeroChkPure(nodep,$lhsp) )\n");
4211 46 replaceZeroChkPure(nodep,nodep->lhsp());
4212 46 return true;
4213 }
4214 return false;
4215 }
4216 // Generated by astgen
4217 8044 bool match_LogAnd_3(AstLogAnd* nodep) {
4218 // TREEOP ("AstLogAnd{$lhsp.isNeqZero, $rhsp}", "replaceWRhsBool(nodep)")
4219
4/4
✓ Branch 0 taken 4167 times.
✓ Branch 1 taken 3877 times.
✓ Branch 3 taken 3834 times.
✓ Branch 4 taken 333 times.
8044 if (m_doNConst && nodep->lhsp()->isNeqZero()) {
4220
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 333 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
333 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstLogAnd $lhsp.isNeqZero, $rhsp , replaceWRhsBool(nodep) )\n");
4221 replaceWRhsBool(nodep);
4222 333 return true;
4223 }
4224 return false;
4225 }
4226 // Generated by astgen
4227 7711 bool match_LogAnd_4(AstLogAnd* nodep) {
4228 // TREEOP ("AstLogAnd{$lhsp, $rhsp.isNeqZero}", "replaceWLhsBool(nodep)")
4229
4/4
✓ Branch 0 taken 3834 times.
✓ Branch 1 taken 3877 times.
✓ Branch 3 taken 3485 times.
✓ Branch 4 taken 349 times.
7711 if (m_doNConst && nodep->rhsp()->isNeqZero()) {
4230
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 349 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
349 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstLogAnd $lhsp, $rhsp.isNeqZero , replaceWLhsBool(nodep) )\n");
4231 replaceWLhsBool(nodep);
4232 349 return true;
4233 }
4234 return false;
4235 }
4236 // Generated by astgen
4237 7362 bool match_LogAnd_5(AstLogAnd* nodep) {
4238 // TREEOP ("AstLogAnd {operandsSame($lhsp,,$rhsp)}", "replaceWLhsBool(nodep)")
4239
3/4
✓ Branch 0 taken 3485 times.
✓ Branch 1 taken 3877 times.
✓ Branch 3 taken 3485 times.
✗ Branch 4 not taken.
7362 if (m_doNConst && operandsSame(nodep->lhsp(),nodep->rhsp())) {
4240 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstLogAnd operandsSame($lhsp,,$rhsp) , replaceWLhsBool(nodep) )\n");
4241 replaceWLhsBool(nodep);
4242 return true;
4243 }
4244 return false;
4245 }
4246 // Generated by astgen
4247 7362 bool match_LogAnd_6(AstLogAnd* nodep) {
4248 // TREEOPV("AstLogAnd{matchBiopToBitwise(nodep)}", "AstAnd{$lhsp,$rhsp}")
4249
4/4
✓ Branch 0 taken 3403 times.
✓ Branch 1 taken 3959 times.
✓ Branch 3 taken 255 times.
✓ Branch 4 taken 3148 times.
7362 if (m_doV && matchBiopToBitwise(nodep)) {
4250
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 3148 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
3148 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstLogAnd matchBiopToBitwise(nodep) , AstAnd $lhsp,$rhsp )\n");
4251 AstNodeExpr* arg1p = nodep->lhsp()->unlinkFrBack();
4252 AstNodeExpr* arg2p = nodep->rhsp()->unlinkFrBack();
4253
1/2
✓ Branch 2 taken 3148 times.
✗ Branch 3 not taken.
3148 AstNodeExpr* newp = new AstAnd(nodep->fileline(), arg1p, arg2p);
4254 3148 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
4255 3148 return true;
4256 }
4257 return false;
4258 }
4259 // Generated by astgen
4260 bool match_LogEq_0(AstLogEq* nodep) {
4261 // TREEOPV("AstLogEq{$lhsp, $rhsp}", "replaceLogEq(nodep)")
4262 if (m_doV) {
4263 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstLogEq $lhsp, $rhsp , replaceLogEq(nodep) )\n");
4264 replaceLogEq(nodep);
4265 return true;
4266 }
4267 return false;
4268 }
4269 // Generated by astgen
4270 bool match_LogIf_0(AstLogIf* nodep) {
4271 // TREEOPS("AstLogIf{$lhsp.isZero}", "replaceNum(nodep, 1)")
4272 if (m_doNConst && nodep->lhsp()->isZero()) {
4273 UINFO(7, cvtToHex(nodep) << " TREEOPS( AstLogIf $lhsp.isZero , replaceNum(nodep, 1) )\n");
4274 replaceNum(nodep, 1);
4275 return true;
4276 }
4277 return false;
4278 }
4279 // Generated by astgen
4280 bool match_LogIf_1(AstLogIf* nodep) {
4281 // TREEOPV("AstLogIf{$lhsp, $rhsp}", "AstLogOr{AstLogNot{$lhsp},$rhsp}")
4282 if (m_doV) {
4283 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstLogIf $lhsp, $rhsp , AstLogOr AstLogNot $lhsp ,$rhsp )\n");
4284 AstNodeExpr* arg1p = nodep->lhsp()->unlinkFrBack();
4285 AstNodeExpr* arg2p = nodep->rhsp()->unlinkFrBack();
4286 AstNodeExpr* newp = new AstLogOr(nodep->fileline(), new AstLogNot(nodep->fileline(), arg1p), arg2p);
4287 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
4288 return true;
4289 }
4290 return false;
4291 }
4292 // Generated by astgen
4293 65834 bool match_LogNot_0(AstLogNot* nodep) {
4294 // TREEOP ("AstLogNot{$lhsp.castLogNot}", "replaceWChild(nodep, $lhsp->castLogNot()->lhsp())")
4295
2/2
✓ Branch 0 taken 33359 times.
✓ Branch 1 taken 32475 times.
65834 if (m_doNConst && VN_IS(nodep->lhsp(),LogNot)) {
4296 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstLogNot $lhsp.castLogNot , replaceWChild(nodep, $lhsp->castLogNot()->lhsp()) )\n");
4297 replaceWChild(nodep, VN_CAST(nodep->lhsp(),LogNot)->lhsp());
4298 return true;
4299 }
4300 return false;
4301 }
4302 // Generated by astgen
4303 65834 bool match_LogNot_1(AstLogNot* nodep) {
4304 // TREEOP ("AstLogNot{$lhsp.castEqCase}", "AstNeqCase{$lhsp->castEqCase()->lhsp(),$lhsp->castEqCase()->rhsp()}")
4305
2/2
✓ Branch 0 taken 33359 times.
✓ Branch 1 taken 32475 times.
65834 if (m_doNConst && VN_IS(nodep->lhsp(),EqCase)) {
4306 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstLogNot $lhsp.castEqCase , AstNeqCase $lhsp->castEqCase()->lhsp(),$lhsp->castEqCase()->rhsp() )\n");
4307 AstNodeExpr* arg1p = VN_CAST(nodep->lhsp(),EqCase)->lhsp()->unlinkFrBack();
4308 AstNodeExpr* arg2p = VN_CAST(nodep->lhsp(),EqCase)->rhsp()->unlinkFrBack();
4309 AstNodeExpr* newp = new AstNeqCase(nodep->fileline(), arg1p, arg2p);
4310 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
4311 return true;
4312 }
4313 return false;
4314 }
4315 // Generated by astgen
4316 65834 bool match_LogNot_2(AstLogNot* nodep) {
4317 // TREEOP ("AstLogNot{$lhsp.castNeqCase}", "AstEqCase {$lhsp->castNeqCase()->lhsp(),$lhsp->castNeqCase()->rhsp()}")
4318
2/2
✓ Branch 0 taken 33359 times.
✓ Branch 1 taken 32475 times.
65834 if (m_doNConst && VN_IS(nodep->lhsp(),NeqCase)) {
4319 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstLogNot $lhsp.castNeqCase , AstEqCase $lhsp->castNeqCase()->lhsp(),$lhsp->castNeqCase()->rhsp() )\n");
4320 AstNodeExpr* arg1p = VN_CAST(nodep->lhsp(),NeqCase)->lhsp()->unlinkFrBack();
4321 AstNodeExpr* arg2p = VN_CAST(nodep->lhsp(),NeqCase)->rhsp()->unlinkFrBack();
4322 AstNodeExpr* newp = new AstEqCase(nodep->fileline(), arg1p, arg2p);
4323 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
4324 return true;
4325 }
4326 return false;
4327 }
4328 // Generated by astgen
4329 65834 bool match_LogNot_3(AstLogNot* nodep) {
4330 // TREEOP ("AstLogNot{$lhsp.castEqWild}", "AstNeqWild{$lhsp->castEqWild()->lhsp(),$lhsp->castEqWild()->rhsp()}")
4331
2/2
✓ Branch 0 taken 33359 times.
✓ Branch 1 taken 32475 times.
65834 if (m_doNConst && VN_IS(nodep->lhsp(),EqWild)) {
4332 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstLogNot $lhsp.castEqWild , AstNeqWild $lhsp->castEqWild()->lhsp(),$lhsp->castEqWild()->rhsp() )\n");
4333 AstNodeExpr* arg1p = VN_CAST(nodep->lhsp(),EqWild)->lhsp()->unlinkFrBack();
4334 AstNodeExpr* arg2p = VN_CAST(nodep->lhsp(),EqWild)->rhsp()->unlinkFrBack();
4335 AstNodeExpr* newp = new AstNeqWild(nodep->fileline(), arg1p, arg2p);
4336 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
4337 return true;
4338 }
4339 return false;
4340 }
4341 // Generated by astgen
4342 65834 bool match_LogNot_4(AstLogNot* nodep) {
4343 // TREEOP ("AstLogNot{$lhsp.castNeqWild}", "AstEqWild {$lhsp->castNeqWild()->lhsp(),$lhsp->castNeqWild()->rhsp()}")
4344
2/2
✓ Branch 0 taken 33359 times.
✓ Branch 1 taken 32475 times.
65834 if (m_doNConst && VN_IS(nodep->lhsp(),NeqWild)) {
4345 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstLogNot $lhsp.castNeqWild , AstEqWild $lhsp->castNeqWild()->lhsp(),$lhsp->castNeqWild()->rhsp() )\n");
4346 AstNodeExpr* arg1p = VN_CAST(nodep->lhsp(),NeqWild)->lhsp()->unlinkFrBack();
4347 AstNodeExpr* arg2p = VN_CAST(nodep->lhsp(),NeqWild)->rhsp()->unlinkFrBack();
4348 AstNodeExpr* newp = new AstEqWild(nodep->fileline(), arg1p, arg2p);
4349 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
4350 return true;
4351 }
4352 return false;
4353 }
4354 // Generated by astgen
4355 65834 bool match_LogNot_5(AstLogNot* nodep) {
4356 // TREEOP ("AstLogNot{$lhsp.castEq}", "AstNeq {$lhsp->castEq()->lhsp(),$lhsp->castEq()->rhsp()}")
4357
2/2
✓ Branch 0 taken 33359 times.
✓ Branch 1 taken 32475 times.
65834 if (m_doNConst && VN_IS(nodep->lhsp(),Eq)) {
4358
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 221 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
221 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstLogNot $lhsp.castEq , AstNeq $lhsp->castEq()->lhsp(),$lhsp->castEq()->rhsp() )\n");
4359 AstNodeExpr* arg1p = VN_CAST(nodep->lhsp(),Eq)->lhsp()->unlinkFrBack();
4360 AstNodeExpr* arg2p = VN_CAST(nodep->lhsp(),Eq)->rhsp()->unlinkFrBack();
4361
1/2
✓ Branch 2 taken 221 times.
✗ Branch 3 not taken.
221 AstNodeExpr* newp = new AstNeq(nodep->fileline(), arg1p, arg2p);
4362 221 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
4363 221 return true;
4364 }
4365 return false;
4366 }
4367 // Generated by astgen
4368 65613 bool match_LogNot_6(AstLogNot* nodep) {
4369 // TREEOP ("AstLogNot{$lhsp.castNeq}", "AstEq {$lhsp->castNeq()->lhsp(),$lhsp->castNeq()->rhsp()}")
4370
2/2
✓ Branch 0 taken 33138 times.
✓ Branch 1 taken 32475 times.
65613 if (m_doNConst && VN_IS(nodep->lhsp(),Neq)) {
4371
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 215 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
215 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstLogNot $lhsp.castNeq , AstEq $lhsp->castNeq()->lhsp(),$lhsp->castNeq()->rhsp() )\n");
4372 AstNodeExpr* arg1p = VN_CAST(nodep->lhsp(),Neq)->lhsp()->unlinkFrBack();
4373 AstNodeExpr* arg2p = VN_CAST(nodep->lhsp(),Neq)->rhsp()->unlinkFrBack();
4374
1/2
✓ Branch 2 taken 215 times.
✗ Branch 3 not taken.
215 AstNodeExpr* newp = new AstEq(nodep->fileline(), arg1p, arg2p);
4375 215 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
4376 215 return true;
4377 }
4378 return false;
4379 }
4380 // Generated by astgen
4381 65398 bool match_LogNot_7(AstLogNot* nodep) {
4382 // TREEOP ("AstLogNot{$lhsp.castLt}", "AstGte {$lhsp->castLt()->lhsp(),$lhsp->castLt()->rhsp()}")
4383
2/2
✓ Branch 0 taken 32923 times.
✓ Branch 1 taken 32475 times.
65398 if (m_doNConst && VN_IS(nodep->lhsp(),Lt)) {
4384
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 192 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
192 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstLogNot $lhsp.castLt , AstGte $lhsp->castLt()->lhsp(),$lhsp->castLt()->rhsp() )\n");
4385 AstNodeExpr* arg1p = VN_CAST(nodep->lhsp(),Lt)->lhsp()->unlinkFrBack();
4386 AstNodeExpr* arg2p = VN_CAST(nodep->lhsp(),Lt)->rhsp()->unlinkFrBack();
4387
1/2
✓ Branch 2 taken 192 times.
✗ Branch 3 not taken.
192 AstNodeExpr* newp = new AstGte(nodep->fileline(), arg1p, arg2p);
4388 192 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
4389 192 return true;
4390 }
4391 return false;
4392 }
4393 // Generated by astgen
4394 65206 bool match_LogNot_8(AstLogNot* nodep) {
4395 // TREEOP ("AstLogNot{$lhsp.castLtS}", "AstGteS{$lhsp->castLtS()->lhsp(),$lhsp->castLtS()->rhsp()}")
4396
2/2
✓ Branch 0 taken 32731 times.
✓ Branch 1 taken 32475 times.
65206 if (m_doNConst && VN_IS(nodep->lhsp(),LtS)) {
4397
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 29 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
29 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstLogNot $lhsp.castLtS , AstGteS $lhsp->castLtS()->lhsp(),$lhsp->castLtS()->rhsp() )\n");
4398 AstNodeExpr* arg1p = VN_CAST(nodep->lhsp(),LtS)->lhsp()->unlinkFrBack();
4399 AstNodeExpr* arg2p = VN_CAST(nodep->lhsp(),LtS)->rhsp()->unlinkFrBack();
4400
1/2
✓ Branch 2 taken 29 times.
✗ Branch 3 not taken.
29 AstNodeExpr* newp = new AstGteS(nodep->fileline(), arg1p, arg2p);
4401 29 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
4402 29 return true;
4403 }
4404 return false;
4405 }
4406 // Generated by astgen
4407 65177 bool match_LogNot_9(AstLogNot* nodep) {
4408 // TREEOP ("AstLogNot{$lhsp.castLte}", "AstGt {$lhsp->castLte()->lhsp(),$lhsp->castLte()->rhsp()}")
4409
2/2
✓ Branch 0 taken 32702 times.
✓ Branch 1 taken 32475 times.
65177 if (m_doNConst && VN_IS(nodep->lhsp(),Lte)) {
4410
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 192 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
192 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstLogNot $lhsp.castLte , AstGt $lhsp->castLte()->lhsp(),$lhsp->castLte()->rhsp() )\n");
4411 AstNodeExpr* arg1p = VN_CAST(nodep->lhsp(),Lte)->lhsp()->unlinkFrBack();
4412 AstNodeExpr* arg2p = VN_CAST(nodep->lhsp(),Lte)->rhsp()->unlinkFrBack();
4413
1/2
✓ Branch 2 taken 192 times.
✗ Branch 3 not taken.
192 AstNodeExpr* newp = new AstGt(nodep->fileline(), arg1p, arg2p);
4414 192 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
4415 192 return true;
4416 }
4417 return false;
4418 }
4419 // Generated by astgen
4420 64985 bool match_LogNot_10(AstLogNot* nodep) {
4421 // TREEOP ("AstLogNot{$lhsp.castLteS}", "AstGtS {$lhsp->castLteS()->lhsp(),$lhsp->castLteS()->rhsp()}")
4422
2/2
✓ Branch 0 taken 32510 times.
✓ Branch 1 taken 32475 times.
64985 if (m_doNConst && VN_IS(nodep->lhsp(),LteS)) {
4423
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 23 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
23 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstLogNot $lhsp.castLteS , AstGtS $lhsp->castLteS()->lhsp(),$lhsp->castLteS()->rhsp() )\n");
4424 AstNodeExpr* arg1p = VN_CAST(nodep->lhsp(),LteS)->lhsp()->unlinkFrBack();
4425 AstNodeExpr* arg2p = VN_CAST(nodep->lhsp(),LteS)->rhsp()->unlinkFrBack();
4426
1/2
✓ Branch 2 taken 23 times.
✗ Branch 3 not taken.
23 AstNodeExpr* newp = new AstGtS(nodep->fileline(), arg1p, arg2p);
4427 23 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
4428 23 return true;
4429 }
4430 return false;
4431 }
4432 // Generated by astgen
4433 64962 bool match_LogNot_11(AstLogNot* nodep) {
4434 // TREEOP ("AstLogNot{$lhsp.castGt}", "AstLte {$lhsp->castGt()->lhsp(),$lhsp->castGt()->rhsp()}")
4435
2/2
✓ Branch 0 taken 32487 times.
✓ Branch 1 taken 32475 times.
64962 if (m_doNConst && VN_IS(nodep->lhsp(),Gt)) {
4436
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 198 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
198 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstLogNot $lhsp.castGt , AstLte $lhsp->castGt()->lhsp(),$lhsp->castGt()->rhsp() )\n");
4437 AstNodeExpr* arg1p = VN_CAST(nodep->lhsp(),Gt)->lhsp()->unlinkFrBack();
4438 AstNodeExpr* arg2p = VN_CAST(nodep->lhsp(),Gt)->rhsp()->unlinkFrBack();
4439
1/2
✓ Branch 2 taken 198 times.
✗ Branch 3 not taken.
198 AstNodeExpr* newp = new AstLte(nodep->fileline(), arg1p, arg2p);
4440 198 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
4441 198 return true;
4442 }
4443 return false;
4444 }
4445 // Generated by astgen
4446 64764 bool match_LogNot_12(AstLogNot* nodep) {
4447 // TREEOP ("AstLogNot{$lhsp.castGtS}", "AstLteS{$lhsp->castGtS()->lhsp(),$lhsp->castGtS()->rhsp()}")
4448
2/2
✓ Branch 0 taken 32289 times.
✓ Branch 1 taken 32475 times.
64764 if (m_doNConst && VN_IS(nodep->lhsp(),GtS)) {
4449
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 17 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
17 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstLogNot $lhsp.castGtS , AstLteS $lhsp->castGtS()->lhsp(),$lhsp->castGtS()->rhsp() )\n");
4450 AstNodeExpr* arg1p = VN_CAST(nodep->lhsp(),GtS)->lhsp()->unlinkFrBack();
4451 AstNodeExpr* arg2p = VN_CAST(nodep->lhsp(),GtS)->rhsp()->unlinkFrBack();
4452
1/2
✓ Branch 2 taken 17 times.
✗ Branch 3 not taken.
17 AstNodeExpr* newp = new AstLteS(nodep->fileline(), arg1p, arg2p);
4453 17 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
4454 17 return true;
4455 }
4456 return false;
4457 }
4458 // Generated by astgen
4459 64747 bool match_LogNot_13(AstLogNot* nodep) {
4460 // TREEOP ("AstLogNot{$lhsp.castGte}", "AstLt {$lhsp->castGte()->lhsp(),$lhsp->castGte()->rhsp()}")
4461
2/2
✓ Branch 0 taken 32272 times.
✓ Branch 1 taken 32475 times.
64747 if (m_doNConst && VN_IS(nodep->lhsp(),Gte)) {
4462
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 184 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
184 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstLogNot $lhsp.castGte , AstLt $lhsp->castGte()->lhsp(),$lhsp->castGte()->rhsp() )\n");
4463 AstNodeExpr* arg1p = VN_CAST(nodep->lhsp(),Gte)->lhsp()->unlinkFrBack();
4464 AstNodeExpr* arg2p = VN_CAST(nodep->lhsp(),Gte)->rhsp()->unlinkFrBack();
4465
1/2
✓ Branch 2 taken 184 times.
✗ Branch 3 not taken.
184 AstNodeExpr* newp = new AstLt(nodep->fileline(), arg1p, arg2p);
4466 184 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
4467 184 return true;
4468 }
4469 return false;
4470 }
4471 // Generated by astgen
4472 64563 bool match_LogNot_14(AstLogNot* nodep) {
4473 // TREEOP ("AstLogNot{$lhsp.castGteS}", "AstLtS {$lhsp->castGteS()->lhsp(),$lhsp->castGteS()->rhsp()}")
4474
2/2
✓ Branch 0 taken 32088 times.
✓ Branch 1 taken 32475 times.
64563 if (m_doNConst && VN_IS(nodep->lhsp(),GteS)) {
4475
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 23 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
23 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstLogNot $lhsp.castGteS , AstLtS $lhsp->castGteS()->lhsp(),$lhsp->castGteS()->rhsp() )\n");
4476 AstNodeExpr* arg1p = VN_CAST(nodep->lhsp(),GteS)->lhsp()->unlinkFrBack();
4477 AstNodeExpr* arg2p = VN_CAST(nodep->lhsp(),GteS)->rhsp()->unlinkFrBack();
4478
1/2
✓ Branch 2 taken 23 times.
✗ Branch 3 not taken.
23 AstNodeExpr* newp = new AstLtS(nodep->fileline(), arg1p, arg2p);
4479 23 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
4480 23 return true;
4481 }
4482 return false;
4483 }
4484 // Generated by astgen
4485 64540 bool match_LogNot_15(AstLogNot* nodep) {
4486 // TREEOPV("AstLogNot{$lhsp.width1}", "AstNot{$lhsp}")
4487
2/2
✓ Branch 0 taken 32065 times.
✓ Branch 1 taken 32475 times.
64540 if (m_doV && nodep->lhsp()->width1()) {
4488
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 32065 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
32065 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstLogNot $lhsp.width1 , AstNot $lhsp )\n");
4489 AstNodeExpr* arg1p = nodep->lhsp()->unlinkFrBack();
4490
1/2
✓ Branch 2 taken 32065 times.
✗ Branch 3 not taken.
32065 AstNodeExpr* newp = new AstNot(nodep->fileline(), arg1p);
4491 32065 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
4492 32065 return true;
4493 }
4494 return false;
4495 }
4496 // Generated by astgen
4497 8396 bool match_LogOr_0(AstLogOr* nodep) {
4498 // TREEOPS("AstLogOr {$lhsp.isOne}", "replaceNum(nodep, 1)")
4499
4/4
✓ Branch 0 taken 4455 times.
✓ Branch 1 taken 3941 times.
✓ Branch 3 taken 3797 times.
✓ Branch 4 taken 658 times.
8396 if (m_doNConst && nodep->lhsp()->isOne()) {
4500
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 658 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
658 UINFO(7, cvtToHex(nodep) << " TREEOPS( AstLogOr $lhsp.isOne , replaceNum(nodep, 1) )\n");
4501 658 replaceNum(nodep, 1);
4502 658 return true;
4503 }
4504 return false;
4505 }
4506 // Generated by astgen
4507 7635 bool match_LogOr_1(AstLogOr* nodep) {
4508 // TREEOP ("AstLogOr {$lhsp.isZero, $rhsp}", "replaceWRhsBool(nodep)")
4509
4/4
✓ Branch 0 taken 3729 times.
✓ Branch 1 taken 3906 times.
✓ Branch 3 taken 3671 times.
✓ Branch 4 taken 58 times.
7635 if (m_doNConst && nodep->lhsp()->isZero()) {
4510
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 58 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
58 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstLogOr $lhsp.isZero, $rhsp , replaceWRhsBool(nodep) )\n");
4511 replaceWRhsBool(nodep);
4512 58 return true;
4513 }
4514 return false;
4515 }
4516 // Generated by astgen
4517 7577 bool match_LogOr_2(AstLogOr* nodep) {
4518 // TREEOP ("AstLogOr {$lhsp, $rhsp.isZero}", "replaceWLhsBool(nodep)")
4519
4/4
✓ Branch 0 taken 3671 times.
✓ Branch 1 taken 3906 times.
✓ Branch 3 taken 3616 times.
✓ Branch 4 taken 55 times.
7577 if (m_doNConst && nodep->rhsp()->isZero()) {
4520
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 55 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
55 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstLogOr $lhsp, $rhsp.isZero , replaceWLhsBool(nodep) )\n");
4521 replaceWLhsBool(nodep);
4522 55 return true;
4523 }
4524 return false;
4525 }
4526 // Generated by astgen
4527 7522 bool match_LogOr_3(AstLogOr* nodep) {
4528 // TREEOP ("AstLogOr {$lhsp.isNeqZero, $rhsp}", "replaceNum(nodep,1)")
4529
3/4
✓ Branch 0 taken 3616 times.
✓ Branch 1 taken 3906 times.
✓ Branch 3 taken 3616 times.
✗ Branch 4 not taken.
7522 if (m_doNConst && nodep->lhsp()->isNeqZero()) {
4530 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstLogOr $lhsp.isNeqZero, $rhsp , replaceNum(nodep,1) )\n");
4531 replaceNum(nodep,1);
4532 return true;
4533 }
4534 return false;
4535 }
4536 // Generated by astgen
4537 7522 bool match_LogOr_4(AstLogOr* nodep) {
4538 // TREEOP ("AstLogOr {$lhsp, $rhsp.isNeqZero, $lhsp.isPure, nodep->isPure()}", "replaceNum(nodep,1)")
4539
6/8
✓ Branch 0 taken 3616 times.
✓ Branch 1 taken 3906 times.
✓ Branch 3 taken 3247 times.
✓ Branch 4 taken 369 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 369 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 369 times.
7522 if (m_doNConst && nodep->rhsp()->isNeqZero() && nodep->lhsp()->isPure() && nodep->isPure()) {
4540
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 369 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
369 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstLogOr $lhsp, $rhsp.isNeqZero, $lhsp.isPure, nodep->isPure() , replaceNum(nodep,1) )\n");
4541 369 replaceNum(nodep,1);
4542 369 return true;
4543 }
4544 return false;
4545 }
4546 // Generated by astgen
4547 7153 bool match_LogOr_5(AstLogOr* nodep) {
4548 // TREEOP ("AstLogOr {operandsSame($lhsp,,$rhsp)}", "replaceWLhsBool(nodep)")
4549
3/4
✓ Branch 0 taken 3247 times.
✓ Branch 1 taken 3906 times.
✓ Branch 3 taken 3247 times.
✗ Branch 4 not taken.
7153 if (m_doNConst && operandsSame(nodep->lhsp(),nodep->rhsp())) {
4550 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstLogOr operandsSame($lhsp,,$rhsp) , replaceWLhsBool(nodep) )\n");
4551 replaceWLhsBool(nodep);
4552 return true;
4553 }
4554 return false;
4555 }
4556 // Generated by astgen
4557 7153 bool match_LogOr_6(AstLogOr* nodep) {
4558 // TREEOPV("AstLogOr {matchBiopToBitwise(nodep)}", "AstOr{$lhsp,$rhsp}")
4559
4/4
✓ Branch 0 taken 3237 times.
✓ Branch 1 taken 3916 times.
✓ Branch 3 taken 118 times.
✓ Branch 4 taken 3119 times.
7153 if (m_doV && matchBiopToBitwise(nodep)) {
4560
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 3119 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
3119 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstLogOr matchBiopToBitwise(nodep) , AstOr $lhsp,$rhsp )\n");
4561 AstNodeExpr* arg1p = nodep->lhsp()->unlinkFrBack();
4562 AstNodeExpr* arg2p = nodep->rhsp()->unlinkFrBack();
4563
1/2
✓ Branch 2 taken 3119 times.
✗ Branch 3 not taken.
3119 AstNodeExpr* newp = new AstOr(nodep->fileline(), arg1p, arg2p);
4564 3119 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
4565 3119 return true;
4566 }
4567 return false;
4568 }
4569 // Generated by astgen
4570 52510 bool match_Lt_0(AstLt* nodep) {
4571 // TREEOP ("AstLt {!$lhsp.castConst,$rhsp.castConst}", "AstGt {$rhsp,$lhsp}")
4572
2/2
✓ Branch 0 taken 48890 times.
✓ Branch 1 taken 3620 times.
52510 if (m_doNConst && !VN_IS(nodep->lhsp(),Const) && VN_IS(nodep->rhsp(),Const)) {
4573
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 353 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
353 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstLt !$lhsp.castConst,$rhsp.castConst , AstGt $rhsp,$lhsp )\n");
4574 AstNodeExpr* arg1p = nodep->rhsp()->unlinkFrBack();
4575 AstNodeExpr* arg2p = nodep->lhsp()->unlinkFrBack();
4576
1/2
✓ Branch 2 taken 353 times.
✗ Branch 3 not taken.
353 AstNodeExpr* newp = new AstGt(nodep->fileline(), arg1p, arg2p);
4577 353 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
4578 353 return true;
4579 }
4580 return false;
4581 }
4582 // Generated by astgen
4583 53032 bool match_Lt_1(AstLt* nodep) {
4584 // TREEOP1("AstLt {$lhsp, $rhsp.isZero}", "replaceNumSigned(nodep,0)")
4585
4/4
✓ Branch 0 taken 49373 times.
✓ Branch 1 taken 3659 times.
✓ Branch 3 taken 49189 times.
✓ Branch 4 taken 184 times.
53032 if (m_doNConst && nodep->rhsp()->isZero()) {
4586
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 184 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
184 UINFO(7, cvtToHex(nodep) << " TREEOP1( AstLt $lhsp, $rhsp.isZero , replaceNumSigned(nodep,0) )\n");
4587 184 replaceNumSigned(nodep,0);
4588 184 return true;
4589 }
4590 return false;
4591 }
4592 // Generated by astgen
4593 53062 bool match_Lt_2(AstLt* nodep) {
4594 // TREEOP1("AstLt {$lhsp.isAllOnes, $rhsp, $lhsp->width()==$rhsp->width()}", "replaceNumLimited(nodep,0)")
4595
5/6
✓ Branch 0 taken 49403 times.
✓ Branch 1 taken 3659 times.
✓ Branch 3 taken 49373 times.
✓ Branch 4 taken 30 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 30 times.
53092 if (m_doNConst && nodep->lhsp()->isAllOnes() && nodep->lhsp()->width()==nodep->rhsp()->width()) {
4596
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 30 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
30 UINFO(7, cvtToHex(nodep) << " TREEOP1( AstLt $lhsp.isAllOnes, $rhsp, $lhsp->width()==$rhsp->width() , replaceNumLimited(nodep,0) )\n");
4597 30 replaceNumLimited(nodep,0);
4598 30 return true;
4599 }
4600 return false;
4601 }
4602 // Generated by astgen
4603 52157 bool match_Lt_3(AstLt* nodep) {
4604 // TREEOPV("AstLt {$rhsp.castExtend,operandBiExtendConstShrink(nodep)}", "DONE")
4605
4/4
✓ Branch 0 taken 40542 times.
✓ Branch 1 taken 11615 times.
✓ Branch 3 taken 11453 times.
✓ Branch 4 taken 124 times.
63734 if (m_doV && VN_IS(nodep->rhsp(),Extend) && operandBiExtendConstShrink(nodep)) {
4606
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 124 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
124 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstLt $rhsp.castExtend,operandBiExtendConstShrink(nodep) , DONE )\n");
4607
4608 124 return true;
4609 }
4610 return false;
4611 }
4612 // Generated by astgen
4613 52033 bool match_Lt_4(AstLt* nodep) {
4614 // TREEOPV("AstLt {$rhsp.castExtend,operandBiExtendConstOver(nodep)}", "replaceZero(nodep)")
4615
4/4
✓ Branch 0 taken 40418 times.
✓ Branch 1 taken 11615 times.
✓ Branch 3 taken 11213 times.
✓ Branch 4 taken 240 times.
63486 if (m_doV && VN_IS(nodep->rhsp(),Extend) && operandBiExtendConstOver(nodep)) {
4616
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 240 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
240 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstLt $rhsp.castExtend,operandBiExtendConstOver(nodep) , replaceZero(nodep) )\n");
4617 replaceZero(nodep);
4618 240 return true;
4619 }
4620 return false;
4621 }
4622 // Generated by astgen
4623 51793 bool match_Lt_5(AstLt* nodep) {
4624 // TREEOP ("AstLt {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)")
4625
4/4
✓ Branch 0 taken 48173 times.
✓ Branch 1 taken 3620 times.
✓ Branch 3 taken 48141 times.
✓ Branch 4 taken 32 times.
51793 if (m_doNConst && operandsSame(nodep->lhsp(),nodep->rhsp())) {
4626
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
32 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstLt operandsSame($lhsp,,$rhsp) , replaceZero(nodep) )\n");
4627 replaceZero(nodep);
4628 32 return true;
4629 }
4630 return false;
4631 }
4632 // Generated by astgen
4633 51761 bool match_Lt_6(AstLt* nodep) {
4634 // TREEOPV("AstLt {$rhsp.width1, $lhsp.isZero, $rhsp}", "replaceWRhs(nodep)")
4635
4/4
✓ Branch 0 taken 40147 times.
✓ Branch 1 taken 11614 times.
✓ Branch 3 taken 1546 times.
✓ Branch 4 taken 54 times.
53361 if (m_doV && nodep->rhsp()->width1() && nodep->lhsp()->isZero()) {
4636
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 54 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
54 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstLt $rhsp.width1, $lhsp.isZero, $rhsp , replaceWRhs(nodep) )\n");
4637 replaceWRhs(nodep);
4638 54 return true;
4639 }
4640 return false;
4641 }
4642 // Generated by astgen
4643 bool match_LtD_0(AstLtD* nodep) {
4644 // TREEOP ("AstLtD {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)")
4645 if (m_doNConst && operandsSame(nodep->lhsp(),nodep->rhsp())) {
4646 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstLtD operandsSame($lhsp,,$rhsp) , replaceZero(nodep) )\n");
4647 replaceZero(nodep);
4648 return true;
4649 }
4650 return false;
4651 }
4652 // Generated by astgen
4653 bool match_LtN_0(AstLtN* nodep) {
4654 // TREEOP ("AstLtN {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)")
4655 if (m_doNConst && operandsSame(nodep->lhsp(),nodep->rhsp())) {
4656 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstLtN operandsSame($lhsp,,$rhsp) , replaceZero(nodep) )\n");
4657 replaceZero(nodep);
4658 return true;
4659 }
4660 return false;
4661 }
4662 // Generated by astgen
4663 3555 bool match_LtS_0(AstLtS* nodep) {
4664 // TREEOP ("AstLtS {!$lhsp.castConst,$rhsp.castConst}", "AstGtS {$rhsp,$lhsp}")
4665
2/2
✓ Branch 0 taken 3221 times.
✓ Branch 1 taken 334 times.
3555 if (m_doNConst && !VN_IS(nodep->lhsp(),Const) && VN_IS(nodep->rhsp(),Const)) {
4666
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 23 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
23 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstLtS !$lhsp.castConst,$rhsp.castConst , AstGtS $rhsp,$lhsp )\n");
4667 AstNodeExpr* arg1p = nodep->rhsp()->unlinkFrBack();
4668 AstNodeExpr* arg2p = nodep->lhsp()->unlinkFrBack();
4669
1/2
✓ Branch 2 taken 23 times.
✗ Branch 3 not taken.
23 AstNodeExpr* newp = new AstGtS(nodep->fileline(), arg1p, arg2p);
4670 23 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
4671 23 return true;
4672 }
4673 return false;
4674 }
4675 // Generated by astgen
4676 3532 bool match_LtS_1(AstLtS* nodep) {
4677 // TREEOP ("AstLtS {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)")
4678
4/4
✓ Branch 0 taken 3198 times.
✓ Branch 1 taken 334 times.
✓ Branch 3 taken 3171 times.
✓ Branch 4 taken 27 times.
3532 if (m_doNConst && operandsSame(nodep->lhsp(),nodep->rhsp())) {
4679
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 27 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
27 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstLtS operandsSame($lhsp,,$rhsp) , replaceZero(nodep) )\n");
4680 replaceZero(nodep);
4681 27 return true;
4682 }
4683 return false;
4684 }
4685 // Generated by astgen
4686 40096 bool match_Lte_0(AstLte* nodep) {
4687 // TREEOP ("AstLte {!$lhsp.castConst,$rhsp.castConst}", "AstGte {$rhsp,$lhsp}")
4688
2/2
✓ Branch 0 taken 36585 times.
✓ Branch 1 taken 3511 times.
40096 if (m_doNConst && !VN_IS(nodep->lhsp(),Const) && VN_IS(nodep->rhsp(),Const)) {
4689
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 466 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
466 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstLte !$lhsp.castConst,$rhsp.castConst , AstGte $rhsp,$lhsp )\n");
4690 AstNodeExpr* arg1p = nodep->rhsp()->unlinkFrBack();
4691 AstNodeExpr* arg2p = nodep->lhsp()->unlinkFrBack();
4692
1/2
✓ Branch 2 taken 466 times.
✗ Branch 3 not taken.
466 AstNodeExpr* newp = new AstGte(nodep->fileline(), arg1p, arg2p);
4693 466 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
4694 466 return true;
4695 }
4696 return false;
4697 }
4698 // Generated by astgen
4699 40619 bool match_Lte_1(AstLte* nodep) {
4700 // TREEOP1("AstLte {$lhsp.isZero, $rhsp}", "replaceNumSigned(nodep,1)")
4701
4/4
✓ Branch 0 taken 37066 times.
✓ Branch 1 taken 3553 times.
✓ Branch 3 taken 36862 times.
✓ Branch 4 taken 204 times.
40619 if (m_doNConst && nodep->lhsp()->isZero()) {
4702
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 204 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
204 UINFO(7, cvtToHex(nodep) << " TREEOP1( AstLte $lhsp.isZero, $rhsp , replaceNumSigned(nodep,1) )\n");
4703 204 replaceNumSigned(nodep,1);
4704 204 return true;
4705 }
4706 return false;
4707 }
4708 // Generated by astgen
4709 40653 bool match_Lte_2(AstLte* nodep) {
4710 // TREEOP1("AstLte {$lhsp, $rhsp.isAllOnes, $lhsp->width()==$rhsp->width()}", "replaceNumLimited(nodep,1)")
4711
5/6
✓ Branch 0 taken 37100 times.
✓ Branch 1 taken 3553 times.
✓ Branch 3 taken 37066 times.
✓ Branch 4 taken 34 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 34 times.
40687 if (m_doNConst && nodep->rhsp()->isAllOnes() && nodep->lhsp()->width()==nodep->rhsp()->width()) {
4712
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 34 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
34 UINFO(7, cvtToHex(nodep) << " TREEOP1( AstLte $lhsp, $rhsp.isAllOnes, $lhsp->width()==$rhsp->width() , replaceNumLimited(nodep,1) )\n");
4713 34 replaceNumLimited(nodep,1);
4714 34 return true;
4715 }
4716 return false;
4717 }
4718 // Generated by astgen
4719 39630 bool match_Lte_3(AstLte* nodep) {
4720 // TREEOPV("AstLte {$rhsp.castExtend,operandBiExtendConstShrink(nodep)}", "DONE")
4721
4/4
✓ Branch 0 taken 32435 times.
✓ Branch 1 taken 7195 times.
✓ Branch 3 taken 11231 times.
✓ Branch 4 taken 29 times.
50890 if (m_doV && VN_IS(nodep->rhsp(),Extend) && operandBiExtendConstShrink(nodep)) {
4722
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 29 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
29 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstLte $rhsp.castExtend,operandBiExtendConstShrink(nodep) , DONE )\n");
4723
4724 29 return true;
4725 }
4726 return false;
4727 }
4728 // Generated by astgen
4729 39601 bool match_Lte_4(AstLte* nodep) {
4730 // TREEOPV("AstLte {$rhsp.castExtend,operandBiExtendConstOver(nodep)}", "replaceZero(nodep)")
4731
4/4
✓ Branch 0 taken 32406 times.
✓ Branch 1 taken 7195 times.
✓ Branch 3 taken 10973 times.
✓ Branch 4 taken 258 times.
50832 if (m_doV && VN_IS(nodep->rhsp(),Extend) && operandBiExtendConstOver(nodep)) {
4732
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 258 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
258 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstLte $rhsp.castExtend,operandBiExtendConstOver(nodep) , replaceZero(nodep) )\n");
4733 replaceZero(nodep);
4734 258 return true;
4735 }
4736 return false;
4737 }
4738 // Generated by astgen
4739 39343 bool match_Lte_5(AstLte* nodep) {
4740 // TREEOP ("AstLte {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)")
4741
4/4
✓ Branch 0 taken 35832 times.
✓ Branch 1 taken 3511 times.
✓ Branch 3 taken 35797 times.
✓ Branch 4 taken 35 times.
39343 if (m_doNConst && operandsSame(nodep->lhsp(),nodep->rhsp())) {
4742
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 35 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
35 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstLte operandsSame($lhsp,,$rhsp) , replaceNum(nodep,1) )\n");
4743 35 replaceNum(nodep,1);
4744 35 return true;
4745 }
4746 return false;
4747 }
4748 // Generated by astgen
4749 39308 bool match_Lte_6(AstLte* nodep) {
4750 // TREEOPV("AstLte {$lhsp->width()==$rhsp->width(), $rhsp.isAllOnes}", "replaceNum(nodep,1)")
4751
4/6
✓ Branch 0 taken 32114 times.
✓ Branch 1 taken 7194 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 32114 times.
✓ Branch 5 taken 32114 times.
✗ Branch 6 not taken.
71422 if (m_doV && nodep->lhsp()->width()==nodep->rhsp()->width() && nodep->rhsp()->isAllOnes()) {
4752 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstLte $lhsp->width()==$rhsp->width(), $rhsp.isAllOnes , replaceNum(nodep,1) )\n");
4753 replaceNum(nodep,1);
4754 return true;
4755 }
4756 return false;
4757 }
4758 // Generated by astgen
4759 bool match_LteD_0(AstLteD* nodep) {
4760 // TREEOP ("AstLteD {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)")
4761 if (m_doNConst && operandsSame(nodep->lhsp(),nodep->rhsp())) {
4762 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstLteD operandsSame($lhsp,,$rhsp) , replaceNum(nodep,1) )\n");
4763 replaceNum(nodep,1);
4764 return true;
4765 }
4766 return false;
4767 }
4768 // Generated by astgen
4769 bool match_LteN_0(AstLteN* nodep) {
4770 // TREEOP ("AstLteN {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)")
4771 if (m_doNConst && operandsSame(nodep->lhsp(),nodep->rhsp())) {
4772 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstLteN operandsSame($lhsp,,$rhsp) , replaceNum(nodep,1) )\n");
4773 replaceNum(nodep,1);
4774 return true;
4775 }
4776 return false;
4777 }
4778 // Generated by astgen
4779 3542 bool match_LteS_0(AstLteS* nodep) {
4780 // TREEOP ("AstLteS {!$lhsp.castConst,$rhsp.castConst}", "AstGteS{$rhsp,$lhsp}")
4781
2/2
✓ Branch 0 taken 3222 times.
✓ Branch 1 taken 320 times.
3542 if (m_doNConst && !VN_IS(nodep->lhsp(),Const) && VN_IS(nodep->rhsp(),Const)) {
4782
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 18 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
18 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstLteS !$lhsp.castConst,$rhsp.castConst , AstGteS $rhsp,$lhsp )\n");
4783 AstNodeExpr* arg1p = nodep->rhsp()->unlinkFrBack();
4784 AstNodeExpr* arg2p = nodep->lhsp()->unlinkFrBack();
4785
1/2
✓ Branch 2 taken 18 times.
✗ Branch 3 not taken.
18 AstNodeExpr* newp = new AstGteS(nodep->fileline(), arg1p, arg2p);
4786 18 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
4787 18 return true;
4788 }
4789 return false;
4790 }
4791 // Generated by astgen
4792 3524 bool match_LteS_1(AstLteS* nodep) {
4793 // TREEOP ("AstLteS {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)")
4794
4/4
✓ Branch 0 taken 3204 times.
✓ Branch 1 taken 320 times.
✓ Branch 3 taken 3188 times.
✓ Branch 4 taken 16 times.
3524 if (m_doNConst && operandsSame(nodep->lhsp(),nodep->rhsp())) {
4795
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 16 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
16 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstLteS operandsSame($lhsp,,$rhsp) , replaceNum(nodep,1) )\n");
4796 16 replaceNum(nodep,1);
4797 16 return true;
4798 }
4799 return false;
4800 }
4801 // Generated by astgen
4802 bool match_ModDiv_0(AstModDiv* nodep) {
4803 // TREEOP ("AstModDiv{$lhsp, operandIsPowTwo($rhsp)}", "replaceModAnd(nodep)")
4804 if (m_doNConst && operandIsPowTwo(nodep->rhsp())) {
4805 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstModDiv $lhsp, operandIsPowTwo($rhsp) , replaceModAnd(nodep) )\n");
4806 replaceModAnd(nodep);
4807 return true;
4808 }
4809 return false;
4810 }
4811 // Generated by astgen
4812 41184 bool match_Mul_0(AstMul* nodep) {
4813 // TREEOP ("AstMul {$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)")
4814
4/4
✓ Branch 0 taken 37575 times.
✓ Branch 1 taken 3609 times.
✓ Branch 3 taken 37375 times.
✓ Branch 4 taken 200 times.
41184 if (m_doNConst && nodep->lhsp()->isZero()) {
4815
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 200 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
200 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstMul $lhsp.isZero, $rhsp , replaceZeroChkPure(nodep,$rhsp) )\n");
4816 200 replaceZeroChkPure(nodep,nodep->rhsp());
4817 200 return true;
4818 }
4819 return false;
4820 }
4821 // Generated by astgen
4822 40984 bool match_Mul_1(AstMul* nodep) {
4823 // TREEOP ("AstMul {$lhsp, $rhsp.isZero}", "replaceZeroChkPure(nodep,$lhsp)")
4824
3/4
✓ Branch 0 taken 37375 times.
✓ Branch 1 taken 3609 times.
✓ Branch 3 taken 37375 times.
✗ Branch 4 not taken.
40984 if (m_doNConst && nodep->rhsp()->isZero()) {
4825 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstMul $lhsp, $rhsp.isZero , replaceZeroChkPure(nodep,$lhsp) )\n");
4826 replaceZeroChkPure(nodep,nodep->lhsp());
4827 return true;
4828 }
4829 return false;
4830 }
4831 // Generated by astgen
4832 40984 bool match_Mul_2(AstMul* nodep) {
4833 // TREEOP ("AstMul {$lhsp.isOne, $rhsp}", "replaceWRhs(nodep)")
4834
4/4
✓ Branch 0 taken 37375 times.
✓ Branch 1 taken 3609 times.
✓ Branch 3 taken 37263 times.
✓ Branch 4 taken 112 times.
40984 if (m_doNConst && nodep->lhsp()->isOne()) {
4835
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 112 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
112 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstMul $lhsp.isOne, $rhsp , replaceWRhs(nodep) )\n");
4836 replaceWRhs(nodep);
4837 112 return true;
4838 }
4839 return false;
4840 }
4841 // Generated by astgen
4842 40872 bool match_Mul_3(AstMul* nodep) {
4843 // TREEOP ("AstMul {operandIsPowTwo($lhsp), operandsSameWidth($lhsp,,$rhsp)}", "replaceMulShift(nodep)")
4844
5/6
✓ Branch 0 taken 37263 times.
✓ Branch 1 taken 3609 times.
✓ Branch 3 taken 37245 times.
✓ Branch 4 taken 18 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 18 times.
40890 if (m_doNConst && operandIsPowTwo(nodep->lhsp()) && operandsSameWidth(nodep->lhsp(),nodep->rhsp())) {
4845
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 18 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
18 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstMul operandIsPowTwo($lhsp), operandsSameWidth($lhsp,,$rhsp) , replaceMulShift(nodep) )\n");
4846 18 replaceMulShift(nodep);
4847 18 return true;
4848 }
4849 return false;
4850 }
4851 // Generated by astgen
4852 2853 bool match_MulS_0(AstMulS* nodep) {
4853 // TREEOP ("AstMulS {$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)")
4854
4/4
✓ Branch 0 taken 2616 times.
✓ Branch 1 taken 237 times.
✓ Branch 3 taken 2605 times.
✓ Branch 4 taken 11 times.
2853 if (m_doNConst && nodep->lhsp()->isZero()) {
4855
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
11 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstMulS $lhsp.isZero, $rhsp , replaceZeroChkPure(nodep,$rhsp) )\n");
4856 11 replaceZeroChkPure(nodep,nodep->rhsp());
4857 11 return true;
4858 }
4859 return false;
4860 }
4861 // Generated by astgen
4862 2842 bool match_MulS_1(AstMulS* nodep) {
4863 // TREEOP ("AstMulS {$lhsp, $rhsp.isZero}", "replaceZeroChkPure(nodep,$lhsp)")
4864
3/4
✓ Branch 0 taken 2605 times.
✓ Branch 1 taken 237 times.
✓ Branch 3 taken 2605 times.
✗ Branch 4 not taken.
2842 if (m_doNConst && nodep->rhsp()->isZero()) {
4865 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstMulS $lhsp, $rhsp.isZero , replaceZeroChkPure(nodep,$lhsp) )\n");
4866 replaceZeroChkPure(nodep,nodep->lhsp());
4867 return true;
4868 }
4869 return false;
4870 }
4871 // Generated by astgen
4872 2842 bool match_MulS_2(AstMulS* nodep) {
4873 // TREEOP ("AstMulS {$lhsp.isOne, $rhsp}", "replaceWRhs(nodep)")
4874
4/4
✓ Branch 0 taken 2605 times.
✓ Branch 1 taken 237 times.
✓ Branch 3 taken 2604 times.
✓ Branch 4 taken 1 times.
2842 if (m_doNConst && nodep->lhsp()->isOne()) {
4875
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
1 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstMulS $lhsp.isOne, $rhsp , replaceWRhs(nodep) )\n");
4876 replaceWRhs(nodep);
4877 1 return true;
4878 }
4879 return false;
4880 }
4881 // Generated by astgen
4882 147925 bool match_Neq_0(AstNeq* nodep) {
4883 // TREEOPV("AstNeq {$rhsp.castExtend,operandBiExtendConstShrink(nodep)}", "DONE")
4884
4/4
✓ Branch 0 taken 35776 times.
✓ Branch 1 taken 112149 times.
✓ Branch 3 taken 11078 times.
✓ Branch 4 taken 89 times.
159092 if (m_doV && VN_IS(nodep->rhsp(),Extend) && operandBiExtendConstShrink(nodep)) {
4885
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 89 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
89 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstNeq $rhsp.castExtend,operandBiExtendConstShrink(nodep) , DONE )\n");
4886
4887 89 return true;
4888 }
4889 return false;
4890 }
4891 // Generated by astgen
4892 147836 bool match_Neq_1(AstNeq* nodep) {
4893 // TREEOPV("AstNeq {$rhsp.castExtend,operandBiExtendConstOver(nodep)}", "replaceNum(nodep,1)")
4894
4/4
✓ Branch 0 taken 35687 times.
✓ Branch 1 taken 112149 times.
✓ Branch 3 taken 10836 times.
✓ Branch 4 taken 242 times.
158914 if (m_doV && VN_IS(nodep->rhsp(),Extend) && operandBiExtendConstOver(nodep)) {
4895
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 242 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
242 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstNeq $rhsp.castExtend,operandBiExtendConstOver(nodep) , replaceNum(nodep,1) )\n");
4896 242 replaceNum(nodep,1);
4897 242 return true;
4898 }
4899 return false;
4900 }
4901 // Generated by astgen
4902 147594 bool match_Neq_2(AstNeq* nodep) {
4903 // TREEOP ("AstNeq {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)")
4904
4/4
✓ Branch 0 taken 143709 times.
✓ Branch 1 taken 3885 times.
✓ Branch 3 taken 143644 times.
✓ Branch 4 taken 65 times.
147594 if (m_doNConst && operandsSame(nodep->lhsp(),nodep->rhsp())) {
4905
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 65 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
65 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstNeq operandsSame($lhsp,,$rhsp) , replaceZero(nodep) )\n");
4906 replaceZero(nodep);
4907 65 return true;
4908 }
4909 return false;
4910 }
4911 // Generated by astgen
4912 147529 bool match_Neq_3(AstNeq* nodep) {
4913 // TREEOPV("AstNeq {$rhsp.width1, $lhsp.isZero, $rhsp}", "replaceWRhs(nodep)")
4914
4/4
✓ Branch 0 taken 35382 times.
✓ Branch 1 taken 112147 times.
✓ Branch 3 taken 1206 times.
✓ Branch 4 taken 44 times.
148779 if (m_doV && nodep->rhsp()->width1() && nodep->lhsp()->isZero()) {
4915
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 44 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
44 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstNeq $rhsp.width1, $lhsp.isZero, $rhsp , replaceWRhs(nodep) )\n");
4916 replaceWRhs(nodep);
4917 44 return true;
4918 }
4919 return false;
4920 }
4921 // Generated by astgen
4922 147485 bool match_Neq_4(AstNeq* nodep) {
4923 // TREEOPV("AstNeq {$lhsp.width1, $lhsp, $rhsp.isZero}", "replaceWLhs(nodep)")
4924
3/4
✓ Branch 0 taken 35338 times.
✓ Branch 1 taken 112147 times.
✓ Branch 3 taken 1206 times.
✗ Branch 4 not taken.
148691 if (m_doV && nodep->lhsp()->width1() && nodep->rhsp()->isZero()) {
4925 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstNeq $lhsp.width1, $lhsp, $rhsp.isZero , replaceWLhs(nodep) )\n");
4926 replaceWLhs(nodep);
4927 return true;
4928 }
4929 return false;
4930 }
4931 // Generated by astgen
4932 147485 bool match_Neq_5(AstNeq* nodep) {
4933 // TREEOPV("AstNeq {$rhsp.width1, $lhsp.isAllOnes, $rhsp}", "AstNot{$rhsp}")
4934
4/4
✓ Branch 0 taken 35338 times.
✓ Branch 1 taken 112147 times.
✓ Branch 3 taken 1178 times.
✓ Branch 4 taken 28 times.
148691 if (m_doV && nodep->rhsp()->width1() && nodep->lhsp()->isAllOnes()) {
4935
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
28 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstNeq $rhsp.width1, $lhsp.isAllOnes, $rhsp , AstNot $rhsp )\n");
4936 AstNodeExpr* arg1p = nodep->rhsp()->unlinkFrBack();
4937
1/2
✓ Branch 2 taken 28 times.
✗ Branch 3 not taken.
28 AstNodeExpr* newp = new AstNot(nodep->fileline(), arg1p);
4938 28 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
4939 28 return true;
4940 }
4941 return false;
4942 }
4943 // Generated by astgen
4944 147457 bool match_Neq_6(AstNeq* nodep) {
4945 // TREEOPV("AstNeq {$lhsp.width1, $lhsp, $rhsp.isAllOnes}", "AstNot{$lhsp}")
4946
3/4
✓ Branch 0 taken 35310 times.
✓ Branch 1 taken 112147 times.
✓ Branch 3 taken 1178 times.
✗ Branch 4 not taken.
148635 if (m_doV && nodep->lhsp()->width1() && nodep->rhsp()->isAllOnes()) {
4947 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstNeq $lhsp.width1, $lhsp, $rhsp.isAllOnes , AstNot $lhsp )\n");
4948 AstNodeExpr* arg1p = nodep->lhsp()->unlinkFrBack();
4949 AstNodeExpr* newp = new AstNot(nodep->fileline(), arg1p);
4950 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
4951 return true;
4952 }
4953 return false;
4954 }
4955 // Generated by astgen
4956 bool match_NeqCase_0(AstNeqCase* nodep) {
4957 // TREEOP ("AstNeqCase{operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)")
4958 if (m_doNConst && operandsSame(nodep->lhsp(),nodep->rhsp())) {
4959 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstNeqCase operandsSame($lhsp,,$rhsp) , replaceZero(nodep) )\n");
4960 replaceZero(nodep);
4961 return true;
4962 }
4963 return false;
4964 }
4965 // Generated by astgen
4966 bool match_NeqD_0(AstNeqD* nodep) {
4967 // TREEOP ("AstNeqD {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)")
4968 if (m_doNConst && operandsSame(nodep->lhsp(),nodep->rhsp())) {
4969 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstNeqD operandsSame($lhsp,,$rhsp) , replaceZero(nodep) )\n");
4970 replaceZero(nodep);
4971 return true;
4972 }
4973 return false;
4974 }
4975 // Generated by astgen
4976 bool match_NeqN_0(AstNeqN* nodep) {
4977 // TREEOP ("AstNeqN {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)")
4978 if (m_doNConst && operandsSame(nodep->lhsp(),nodep->rhsp())) {
4979 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstNeqN operandsSame($lhsp,,$rhsp) , replaceZero(nodep) )\n");
4980 replaceZero(nodep);
4981 return true;
4982 }
4983 return false;
4984 }
4985 // Generated by astgen
4986 bool match_NeqWild_0(AstNeqWild* nodep) {
4987 // TREEOP ("AstNeqWild{operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)")
4988 if (m_doNConst && operandsSame(nodep->lhsp(),nodep->rhsp())) {
4989 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstNeqWild operandsSame($lhsp,,$rhsp) , replaceZero(nodep) )\n");
4990 replaceZero(nodep);
4991 return true;
4992 }
4993 return false;
4994 }
4995 // Generated by astgen
4996 1645198 bool match_NodeBiCom_0(AstNodeBiCom* nodep) {
4997 // TREEOP ("AstNodeBiCom{!$lhsp.castConst, $rhsp.castConst}", "swapSides(nodep)")
4998
2/2
✓ Branch 0 taken 1610345 times.
✓ Branch 1 taken 34853 times.
1645198 if (m_doNConst && !VN_IS(nodep->lhsp(),Const) && VN_IS(nodep->rhsp(),Const)) {
4999
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 43392 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
43392 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstNodeBiCom !$lhsp.castConst, $rhsp.castConst , swapSides(nodep) )\n");
5000 43392 swapSides(nodep);
5001 43392 return true;
5002 }
5003 return false;
5004 }
5005 // Generated by astgen
5006 1393742 bool match_NodeBiComAsv_0(AstNodeBiComAsv* nodep) {
5007 // TREEOP ("AstNodeBiComAsv{operandAsvConst(nodep)}", "replaceAsv(nodep)")
5008
4/4
✓ Branch 0 taken 1366675 times.
✓ Branch 1 taken 27067 times.
✓ Branch 2 taken 10683 times.
✓ Branch 3 taken 1355992 times.
1393742 if (m_doNConst && operandAsvConst(nodep)) {
5009
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 10683 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
10683 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstNodeBiComAsv operandAsvConst(nodep) , replaceAsv(nodep) )\n");
5010 10683 replaceAsv(nodep);
5011 10683 return true;
5012 }
5013 return false;
5014 }
5015 // Generated by astgen
5016 1383059 bool match_NodeBiComAsv_1(AstNodeBiComAsv* nodep) {
5017 // TREEOP ("AstNodeBiComAsv{operandAsvSame(nodep)}", "replaceAsv(nodep)")
5018
4/4
✓ Branch 0 taken 1355992 times.
✓ Branch 1 taken 27067 times.
✓ Branch 3 taken 1355987 times.
✓ Branch 4 taken 5 times.
1383059 if (m_doNConst && operandAsvSame(nodep)) {
5019
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
5 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstNodeBiComAsv operandAsvSame(nodep) , replaceAsv(nodep) )\n");
5020 5 replaceAsv(nodep);
5021 5 return true;
5022 }
5023 return false;
5024 }
5025 // Generated by astgen
5026 1383054 bool match_NodeBiComAsv_2(AstNodeBiComAsv* nodep) {
5027 // TREEOP ("AstNodeBiComAsv{operandAsvLUp(nodep)}", "replaceAsvLUp(nodep)")
5028
4/4
✓ Branch 0 taken 1355987 times.
✓ Branch 1 taken 27067 times.
✓ Branch 2 taken 449 times.
✓ Branch 3 taken 1355538 times.
1383054 if (m_doNConst && operandAsvLUp(nodep)) {
5029
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 449 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
449 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstNodeBiComAsv operandAsvLUp(nodep) , replaceAsvLUp(nodep) )\n");
5030 449 replaceAsvLUp(nodep);
5031 449 return true;
5032 }
5033 return false;
5034 }
5035 // Generated by astgen
5036 1382605 bool match_NodeBiComAsv_3(AstNodeBiComAsv* nodep) {
5037 // TREEOP ("AstNodeBiComAsv{operandAsvRUp(nodep)}", "replaceAsvRUp(nodep)")
5038
4/4
✓ Branch 0 taken 1355538 times.
✓ Branch 1 taken 27067 times.
✓ Branch 2 taken 980 times.
✓ Branch 3 taken 1354558 times.
1382605 if (m_doNConst && operandAsvRUp(nodep)) {
5039
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 980 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
980 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstNodeBiComAsv operandAsvRUp(nodep) , replaceAsvRUp(nodep) )\n");
5040 980 replaceAsvRUp(nodep);
5041 980 return true;
5042 }
5043 return false;
5044 }
5045 // Generated by astgen
5046
1/2
✓ Branch 0 taken 4819722 times.
✗ Branch 1 not taken.
4819722 bool match_NodeBiop_0(AstNodeBiop* nodep) {
5047 // TREEOPA("AstNodeBiop {$lhsp.castConst, $rhsp.castConst, nodep->isPredictOptimizable()}", "replaceConst(nodep)")
5048
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 261036 times.
261036 if (VN_IS(nodep->lhsp(),Const) && VN_IS(nodep->rhsp(),Const) && nodep->isPredictOptimizable()) {
5049
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 261036 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
261036 UINFO(7, cvtToHex(nodep) << " TREEOPA( AstNodeBiop $lhsp.castConst, $rhsp.castConst, nodep->isPredictOptimizable() , replaceConst(nodep) )\n");
5050 261036 replaceConst(nodep);
5051 261036 return true;
5052 }
5053 return false;
5054 }
5055 // Generated by astgen
5056 833911 bool match_NodeCond_0(AstNodeCond* nodep) {
5057 // TREEOP ("AstNodeCond{$condp.isZero, $thenp, $elsep}", "replaceWChild(nodep,$elsep)")
5058
3/4
✓ Branch 0 taken 755093 times.
✓ Branch 1 taken 78818 times.
✓ Branch 3 taken 755093 times.
✗ Branch 4 not taken.
833911 if (m_doNConst && nodep->condp()->isZero()) {
5059 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstNodeCond $condp.isZero, $thenp, $elsep , replaceWChild(nodep,$elsep) )\n");
5060 replaceWChild(nodep,nodep->elsep());
5061 return true;
5062 }
5063 return false;
5064 }
5065 // Generated by astgen
5066 833911 bool match_NodeCond_1(AstNodeCond* nodep) {
5067 // TREEOP ("AstNodeCond{$condp.isNeqZero, $thenp, $elsep}", "replaceWChild(nodep,$thenp)")
5068
3/4
✓ Branch 0 taken 755093 times.
✓ Branch 1 taken 78818 times.
✓ Branch 3 taken 755093 times.
✗ Branch 4 not taken.
833911 if (m_doNConst && nodep->condp()->isNeqZero()) {
5069 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstNodeCond $condp.isNeqZero, $thenp, $elsep , replaceWChild(nodep,$thenp) )\n");
5070 replaceWChild(nodep,nodep->thenp());
5071 return true;
5072 }
5073 return false;
5074 }
5075 // Generated by astgen
5076 833911 bool match_NodeCond_2(AstNodeCond* nodep) {
5077 // TREEOPA("AstNodeCond{$condp.isZero, $thenp.castConst, $elsep.castConst}", "replaceWChild(nodep,$elsep)")
5078
2/2
✓ Branch 1 taken 472 times.
✓ Branch 2 taken 833439 times.
833911 if (nodep->condp()->isZero() && VN_IS(nodep->thenp(),Const) && VN_IS(nodep->elsep(),Const)) {
5079
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
2 UINFO(7, cvtToHex(nodep) << " TREEOPA( AstNodeCond $condp.isZero, $thenp.castConst, $elsep.castConst , replaceWChild(nodep,$elsep) )\n");
5080 2 replaceWChild(nodep,nodep->elsep());
5081 2 return true;
5082 }
5083 return false;
5084 }
5085 // Generated by astgen
5086 833909 bool match_NodeCond_3(AstNodeCond* nodep) {
5087 // TREEOPA("AstNodeCond{$condp.isNeqZero, $thenp.castConst, $elsep.castConst}", "replaceWChild(nodep,$thenp)")
5088
2/2
✓ Branch 1 taken 7168 times.
✓ Branch 2 taken 826741 times.
833909 if (nodep->condp()->isNeqZero() && VN_IS(nodep->thenp(),Const) && VN_IS(nodep->elsep(),Const)) {
5089
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 127 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
127 UINFO(7, cvtToHex(nodep) << " TREEOPA( AstNodeCond $condp.isNeqZero, $thenp.castConst, $elsep.castConst , replaceWChild(nodep,$thenp) )\n");
5090 127 replaceWChild(nodep,nodep->thenp());
5091 127 return true;
5092 }
5093 return false;
5094 }
5095 // Generated by astgen
5096 833782 bool match_NodeCond_4(AstNodeCond* nodep) {
5097 // TREEOP ("AstNodeCond{$condp, operandsSame($thenp,,$elsep)}","replaceWChild(nodep,$thenp)")
5098
4/4
✓ Branch 0 taken 755093 times.
✓ Branch 1 taken 78689 times.
✓ Branch 3 taken 754055 times.
✓ Branch 4 taken 1038 times.
833782 if (m_doNConst && operandsSame(nodep->thenp(),nodep->elsep())) {
5099
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 1038 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
1038 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstNodeCond $condp, operandsSame($thenp,,$elsep) , replaceWChild(nodep,$thenp) )\n");
5100 1038 replaceWChild(nodep,nodep->thenp());
5101 1038 return true;
5102 }
5103 return false;
5104 }
5105 // Generated by astgen
5106 832744 bool match_NodeCond_5(AstNodeCond* nodep) {
5107 // TREEOP ("AstNodeCond{$condp.width1, $thenp.width1, $thenp.isAllOnes, $elsep}", "AstLogOr {$condp, $elsep}")
5108
4/4
✓ Branch 0 taken 754055 times.
✓ Branch 1 taken 78689 times.
✓ Branch 3 taken 13645 times.
✓ Branch 4 taken 93 times.
846482 if (m_doNConst && nodep->condp()->width1() && nodep->thenp()->width1() && nodep->thenp()->isAllOnes()) {
5109
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 93 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
93 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstNodeCond $condp.width1, $thenp.width1, $thenp.isAllOnes, $elsep , AstLogOr $condp, $elsep )\n");
5110 AstNodeExpr* arg1p = nodep->condp()->unlinkFrBack();
5111 AstNodeExpr* arg2p = nodep->elsep()->unlinkFrBack();
5112
1/2
✓ Branch 2 taken 93 times.
✗ Branch 3 not taken.
93 AstNodeExpr* newp = new AstLogOr(nodep->fileline(), arg1p, arg2p);
5113 93 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
5114 93 return true;
5115 }
5116 return false;
5117 }
5118 // Generated by astgen
5119 832651 bool match_NodeCond_6(AstNodeCond* nodep) {
5120 // TREEOP ("AstNodeCond{$condp.width1, $thenp.width1, $thenp, $elsep.isZero, !$elsep.isClassHandleValue}", "AstLogAnd{$condp, $thenp}")
5121
5/6
✓ Branch 0 taken 753962 times.
✓ Branch 1 taken 78689 times.
✓ Branch 3 taken 13541 times.
✓ Branch 4 taken 104 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 104 times.
846296 if (m_doNConst && nodep->condp()->width1() && nodep->thenp()->width1() && nodep->elsep()->isZero() && !nodep->elsep()->isClassHandleValue()) {
5122
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 104 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
104 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstNodeCond $condp.width1, $thenp.width1, $thenp, $elsep.isZero, !$elsep.isClassHandleValue , AstLogAnd $condp, $thenp )\n");
5123 AstNodeExpr* arg1p = nodep->condp()->unlinkFrBack();
5124 AstNodeExpr* arg2p = nodep->thenp()->unlinkFrBack();
5125
1/2
✓ Branch 2 taken 104 times.
✗ Branch 3 not taken.
104 AstNodeExpr* newp = new AstLogAnd(nodep->fileline(), arg1p, arg2p);
5126 104 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
5127 104 return true;
5128 }
5129 return false;
5130 }
5131 // Generated by astgen
5132 832547 bool match_NodeCond_7(AstNodeCond* nodep) {
5133 // TREEOP ("AstNodeCond{$condp.width1, $thenp.width1, $thenp, $elsep.isAllOnes}", "AstLogOr {AstNot{$condp}, $thenp}")
5134
4/4
✓ Branch 0 taken 753858 times.
✓ Branch 1 taken 78689 times.
✓ Branch 3 taken 13434 times.
✓ Branch 4 taken 107 times.
846088 if (m_doNConst && nodep->condp()->width1() && nodep->thenp()->width1() && nodep->elsep()->isAllOnes()) {
5135
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 107 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
107 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstNodeCond $condp.width1, $thenp.width1, $thenp, $elsep.isAllOnes , AstLogOr AstNot $condp , $thenp )\n");
5136 AstNodeExpr* arg1p = nodep->condp()->unlinkFrBack();
5137 AstNodeExpr* arg2p = nodep->thenp()->unlinkFrBack();
5138
3/6
✓ Branch 2 taken 107 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 107 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 107 times.
✗ Branch 9 not taken.
107 AstNodeExpr* newp = new AstLogOr(nodep->fileline(), new AstNot(nodep->fileline(), arg1p), arg2p);
5139 107 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
5140 107 return true;
5141 }
5142 return false;
5143 }
5144 // Generated by astgen
5145 832440 bool match_NodeCond_8(AstNodeCond* nodep) {
5146 // TREEOP ("AstNodeCond{$condp.width1, $thenp.width1, $thenp.isZero, !$thenp.isClassHandleValue, $elsep}", "AstLogAnd{AstNot{$condp}, $elsep}")
5147
5/6
✓ Branch 0 taken 753751 times.
✓ Branch 1 taken 78689 times.
✓ Branch 3 taken 13320 times.
✓ Branch 4 taken 114 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 114 times.
845874 if (m_doNConst && nodep->condp()->width1() && nodep->thenp()->width1() && nodep->thenp()->isZero() && !nodep->thenp()->isClassHandleValue()) {
5148
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 114 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
114 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstNodeCond $condp.width1, $thenp.width1, $thenp.isZero, !$thenp.isClassHandleValue, $elsep , AstLogAnd AstNot $condp , $elsep )\n");
5149 AstNodeExpr* arg1p = nodep->condp()->unlinkFrBack();
5150 AstNodeExpr* arg2p = nodep->elsep()->unlinkFrBack();
5151
3/6
✓ Branch 2 taken 114 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 114 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 114 times.
✗ Branch 9 not taken.
114 AstNodeExpr* newp = new AstLogAnd(nodep->fileline(), new AstNot(nodep->fileline(), arg1p), arg2p);
5152 114 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
5153 114 return true;
5154 }
5155 return false;
5156 }
5157 // Generated by astgen
5158 832326 bool match_NodeCond_9(AstNodeCond* nodep) {
5159 // TREEOP ("AstNodeCond{!$condp.width1, operandBoolShift(nodep->condp())}", "replaceBoolShift(nodep->condp())")
5160
4/4
✓ Branch 0 taken 753637 times.
✓ Branch 1 taken 78689 times.
✓ Branch 3 taken 18559 times.
✓ Branch 4 taken 915 times.
851800 if (m_doNConst && !nodep->condp()->width1() && operandBoolShift(nodep->condp())) {
5161
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 915 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
915 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstNodeCond !$condp.width1, operandBoolShift(nodep->condp()) , replaceBoolShift(nodep->condp()) )\n");
5162 915 replaceBoolShift(nodep->condp());
5163 915 return true;
5164 }
5165 return false;
5166 }
5167 // Generated by astgen
5168 bool match_NodeQuadop_0(AstNodeQuadop* nodep) {
5169 // TREEOPA("AstNodeQuadop{$lhsp.castConst, $rhsp.castConst, $thsp.castConst, $fhsp.castConst}", "replaceConst(nodep)")
5170 if (VN_IS(nodep->lhsp(),Const) && VN_IS(nodep->rhsp(),Const) && VN_IS(nodep->thsp(),Const) && VN_IS(nodep->fhsp(),Const)) {
5171 UINFO(7, cvtToHex(nodep) << " TREEOPA( AstNodeQuadop $lhsp.castConst, $rhsp.castConst, $thsp.castConst, $fhsp.castConst , replaceConst(nodep) )\n");
5172 replaceConst(nodep);
5173 return true;
5174 }
5175 return false;
5176 }
5177 // Generated by astgen
5178
1/2
✓ Branch 0 taken 4176343 times.
✗ Branch 1 not taken.
4176343 bool match_NodeUniop_0(AstNodeUniop* nodep) {
5179 // TREEOPA("AstNodeUniop{$lhsp.castConst, !nodep->isOpaque(), nodep->isPredictOptimizable()}", "replaceConst(nodep)")
5180
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 119493 times.
119493 if (VN_IS(nodep->lhsp(),Const) && !nodep->isOpaque() && nodep->isPredictOptimizable()) {
5181
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 119493 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
119493 UINFO(7, cvtToHex(nodep) << " TREEOPA( AstNodeUniop $lhsp.castConst, !nodep->isOpaque(), nodep->isPredictOptimizable() , replaceConst(nodep) )\n");
5182 119493 replaceConst(nodep);
5183 119493 return true;
5184 }
5185 return false;
5186 }
5187 // Generated by astgen
5188 467567 bool match_Not_0(AstNot* nodep) {
5189 // TREEOP ("AstNot {$lhsp.castNot, $lhsp->width()==VN_AS($lhsp,,Not)->lhsp()->width()}", "replaceWChild(nodep, $lhsp->castNot()->lhsp())")
5190
3/4
✓ Branch 0 taken 453277 times.
✓ Branch 1 taken 14290 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2263 times.
472093 if (m_doNConst && VN_IS(nodep->lhsp(),Not) && nodep->lhsp()->width()==VN_AS(nodep->lhsp(),Not)->lhsp()->width()) {
5191
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 2263 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
2263 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstNot $lhsp.castNot, $lhsp->width()==VN_AS($lhsp,,Not)->lhsp()->width() , replaceWChild(nodep, $lhsp->castNot()->lhsp()) )\n");
5192 2263 replaceWChild(nodep, VN_CAST(nodep->lhsp(),Not)->lhsp());
5193 2263 return true;
5194 }
5195 return false;
5196 }
5197 // Generated by astgen
5198 465304 bool match_Not_1(AstNot* nodep) {
5199 // TREEOPV("AstNot {$lhsp.castEqCase, $lhsp.width1}","AstNeqCase{$lhsp->castEqCase()->lhsp(),$lhsp->castEqCase()->rhsp()}")
5200
2/2
✓ Branch 0 taken 391731 times.
✓ Branch 1 taken 73573 times.
465304 if (m_doV && VN_IS(nodep->lhsp(),EqCase) && nodep->lhsp()->width1()) {
5201 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstNot $lhsp.castEqCase, $lhsp.width1 , AstNeqCase $lhsp->castEqCase()->lhsp(),$lhsp->castEqCase()->rhsp() )\n");
5202 AstNodeExpr* arg1p = VN_CAST(nodep->lhsp(),EqCase)->lhsp()->unlinkFrBack();
5203 AstNodeExpr* arg2p = VN_CAST(nodep->lhsp(),EqCase)->rhsp()->unlinkFrBack();
5204 AstNodeExpr* newp = new AstNeqCase(nodep->fileline(), arg1p, arg2p);
5205 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
5206 return true;
5207 }
5208 return false;
5209 }
5210 // Generated by astgen
5211 465304 bool match_Not_2(AstNot* nodep) {
5212 // TREEOPV("AstNot {$lhsp.castNeqCase, $lhsp.width1}","AstEqCase{$lhsp->castNeqCase()->lhsp(),$lhsp->castNeqCase()->rhsp()}")
5213
2/2
✓ Branch 0 taken 391731 times.
✓ Branch 1 taken 73573 times.
465304 if (m_doV && VN_IS(nodep->lhsp(),NeqCase) && nodep->lhsp()->width1()) {
5214 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstNot $lhsp.castNeqCase, $lhsp.width1 , AstEqCase $lhsp->castNeqCase()->lhsp(),$lhsp->castNeqCase()->rhsp() )\n");
5215 AstNodeExpr* arg1p = VN_CAST(nodep->lhsp(),NeqCase)->lhsp()->unlinkFrBack();
5216 AstNodeExpr* arg2p = VN_CAST(nodep->lhsp(),NeqCase)->rhsp()->unlinkFrBack();
5217 AstNodeExpr* newp = new AstEqCase(nodep->fileline(), arg1p, arg2p);
5218 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
5219 return true;
5220 }
5221 return false;
5222 }
5223 // Generated by astgen
5224 465304 bool match_Not_3(AstNot* nodep) {
5225 // TREEOPV("AstNot {$lhsp.castEqWild, $lhsp.width1}","AstNeqWild{$lhsp->castEqWild()->lhsp(),$lhsp->castEqWild()->rhsp()}")
5226
2/2
✓ Branch 0 taken 391731 times.
✓ Branch 1 taken 73573 times.
465304 if (m_doV && VN_IS(nodep->lhsp(),EqWild) && nodep->lhsp()->width1()) {
5227 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstNot $lhsp.castEqWild, $lhsp.width1 , AstNeqWild $lhsp->castEqWild()->lhsp(),$lhsp->castEqWild()->rhsp() )\n");
5228 AstNodeExpr* arg1p = VN_CAST(nodep->lhsp(),EqWild)->lhsp()->unlinkFrBack();
5229 AstNodeExpr* arg2p = VN_CAST(nodep->lhsp(),EqWild)->rhsp()->unlinkFrBack();
5230 AstNodeExpr* newp = new AstNeqWild(nodep->fileline(), arg1p, arg2p);
5231 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
5232 return true;
5233 }
5234 return false;
5235 }
5236 // Generated by astgen
5237 465304 bool match_Not_4(AstNot* nodep) {
5238 // TREEOPV("AstNot {$lhsp.castNeqWild, $lhsp.width1}","AstEqWild{$lhsp->castNeqWild()->lhsp(),$lhsp->castNeqWild()->rhsp()}")
5239
2/2
✓ Branch 0 taken 391731 times.
✓ Branch 1 taken 73573 times.
465304 if (m_doV && VN_IS(nodep->lhsp(),NeqWild) && nodep->lhsp()->width1()) {
5240 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstNot $lhsp.castNeqWild, $lhsp.width1 , AstEqWild $lhsp->castNeqWild()->lhsp(),$lhsp->castNeqWild()->rhsp() )\n");
5241 AstNodeExpr* arg1p = VN_CAST(nodep->lhsp(),NeqWild)->lhsp()->unlinkFrBack();
5242 AstNodeExpr* arg2p = VN_CAST(nodep->lhsp(),NeqWild)->rhsp()->unlinkFrBack();
5243 AstNodeExpr* newp = new AstEqWild(nodep->fileline(), arg1p, arg2p);
5244 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
5245 return true;
5246 }
5247 return false;
5248 }
5249 // Generated by astgen
5250 465304 bool match_Not_5(AstNot* nodep) {
5251 // TREEOPV("AstNot {$lhsp.castEq, $lhsp.width1}", "AstNeq {$lhsp->castEq()->lhsp(),$lhsp->castEq()->rhsp()}")
5252
2/2
✓ Branch 0 taken 391731 times.
✓ Branch 1 taken 73573 times.
465304 if (m_doV && VN_IS(nodep->lhsp(),Eq) && nodep->lhsp()->width1()) {
5253
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 34 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
34 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstNot $lhsp.castEq, $lhsp.width1 , AstNeq $lhsp->castEq()->lhsp(),$lhsp->castEq()->rhsp() )\n");
5254 AstNodeExpr* arg1p = VN_CAST(nodep->lhsp(),Eq)->lhsp()->unlinkFrBack();
5255 AstNodeExpr* arg2p = VN_CAST(nodep->lhsp(),Eq)->rhsp()->unlinkFrBack();
5256
1/2
✓ Branch 2 taken 34 times.
✗ Branch 3 not taken.
34 AstNodeExpr* newp = new AstNeq(nodep->fileline(), arg1p, arg2p);
5257 34 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
5258 34 return true;
5259 }
5260 return false;
5261 }
5262 // Generated by astgen
5263 465270 bool match_Not_6(AstNot* nodep) {
5264 // TREEOPV("AstNot {$lhsp.castNeq, $lhsp.width1}", "AstEq {$lhsp->castNeq()->lhsp(),$lhsp->castNeq()->rhsp()}")
5265
2/2
✓ Branch 0 taken 391697 times.
✓ Branch 1 taken 73573 times.
465270 if (m_doV && VN_IS(nodep->lhsp(),Neq) && nodep->lhsp()->width1()) {
5266
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 35 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
35 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstNot $lhsp.castNeq, $lhsp.width1 , AstEq $lhsp->castNeq()->lhsp(),$lhsp->castNeq()->rhsp() )\n");
5267 AstNodeExpr* arg1p = VN_CAST(nodep->lhsp(),Neq)->lhsp()->unlinkFrBack();
5268 AstNodeExpr* arg2p = VN_CAST(nodep->lhsp(),Neq)->rhsp()->unlinkFrBack();
5269
1/2
✓ Branch 2 taken 35 times.
✗ Branch 3 not taken.
35 AstNodeExpr* newp = new AstEq(nodep->fileline(), arg1p, arg2p);
5270 35 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
5271 35 return true;
5272 }
5273 return false;
5274 }
5275 // Generated by astgen
5276 465235 bool match_Not_7(AstNot* nodep) {
5277 // TREEOPV("AstNot {$lhsp.castLt, $lhsp.width1}", "AstGte {$lhsp->castLt()->lhsp(),$lhsp->castLt()->rhsp()}")
5278
2/2
✓ Branch 0 taken 391662 times.
✓ Branch 1 taken 73573 times.
465235 if (m_doV && VN_IS(nodep->lhsp(),Lt) && nodep->lhsp()->width1()) {
5279
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 42 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
42 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstNot $lhsp.castLt, $lhsp.width1 , AstGte $lhsp->castLt()->lhsp(),$lhsp->castLt()->rhsp() )\n");
5280 AstNodeExpr* arg1p = VN_CAST(nodep->lhsp(),Lt)->lhsp()->unlinkFrBack();
5281 AstNodeExpr* arg2p = VN_CAST(nodep->lhsp(),Lt)->rhsp()->unlinkFrBack();
5282
1/2
✓ Branch 2 taken 42 times.
✗ Branch 3 not taken.
42 AstNodeExpr* newp = new AstGte(nodep->fileline(), arg1p, arg2p);
5283 42 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
5284 42 return true;
5285 }
5286 return false;
5287 }
5288 // Generated by astgen
5289 465193 bool match_Not_8(AstNot* nodep) {
5290 // TREEOPV("AstNot {$lhsp.castLtS, $lhsp.width1}", "AstGteS{$lhsp->castLtS()->lhsp(),$lhsp->castLtS()->rhsp()}")
5291
2/2
✓ Branch 0 taken 391620 times.
✓ Branch 1 taken 73573 times.
465193 if (m_doV && VN_IS(nodep->lhsp(),LtS) && nodep->lhsp()->width1()) {
5292
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
6 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstNot $lhsp.castLtS, $lhsp.width1 , AstGteS $lhsp->castLtS()->lhsp(),$lhsp->castLtS()->rhsp() )\n");
5293 AstNodeExpr* arg1p = VN_CAST(nodep->lhsp(),LtS)->lhsp()->unlinkFrBack();
5294 AstNodeExpr* arg2p = VN_CAST(nodep->lhsp(),LtS)->rhsp()->unlinkFrBack();
5295
1/2
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 AstNodeExpr* newp = new AstGteS(nodep->fileline(), arg1p, arg2p);
5296 6 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
5297 6 return true;
5298 }
5299 return false;
5300 }
5301 // Generated by astgen
5302 465187 bool match_Not_9(AstNot* nodep) {
5303 // TREEOPV("AstNot {$lhsp.castLte, $lhsp.width1}", "AstGt {$lhsp->castLte()->lhsp(),$lhsp->castLte()->rhsp()}")
5304
2/2
✓ Branch 0 taken 391614 times.
✓ Branch 1 taken 73573 times.
465187 if (m_doV && VN_IS(nodep->lhsp(),Lte) && nodep->lhsp()->width1()) {
5305
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 31 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
31 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstNot $lhsp.castLte, $lhsp.width1 , AstGt $lhsp->castLte()->lhsp(),$lhsp->castLte()->rhsp() )\n");
5306 AstNodeExpr* arg1p = VN_CAST(nodep->lhsp(),Lte)->lhsp()->unlinkFrBack();
5307 AstNodeExpr* arg2p = VN_CAST(nodep->lhsp(),Lte)->rhsp()->unlinkFrBack();
5308
1/2
✓ Branch 2 taken 31 times.
✗ Branch 3 not taken.
31 AstNodeExpr* newp = new AstGt(nodep->fileline(), arg1p, arg2p);
5309 31 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
5310 31 return true;
5311 }
5312 return false;
5313 }
5314 // Generated by astgen
5315 465156 bool match_Not_10(AstNot* nodep) {
5316 // TREEOPV("AstNot {$lhsp.castLteS, $lhsp.width1}", "AstGtS {$lhsp->castLteS()->lhsp(),$lhsp->castLteS()->rhsp()}")
5317
2/2
✓ Branch 0 taken 391583 times.
✓ Branch 1 taken 73573 times.
465156 if (m_doV && VN_IS(nodep->lhsp(),LteS) && nodep->lhsp()->width1()) {
5318
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
7 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstNot $lhsp.castLteS, $lhsp.width1 , AstGtS $lhsp->castLteS()->lhsp(),$lhsp->castLteS()->rhsp() )\n");
5319 AstNodeExpr* arg1p = VN_CAST(nodep->lhsp(),LteS)->lhsp()->unlinkFrBack();
5320 AstNodeExpr* arg2p = VN_CAST(nodep->lhsp(),LteS)->rhsp()->unlinkFrBack();
5321
1/2
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
7 AstNodeExpr* newp = new AstGtS(nodep->fileline(), arg1p, arg2p);
5322 7 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
5323 7 return true;
5324 }
5325 return false;
5326 }
5327 // Generated by astgen
5328 465149 bool match_Not_11(AstNot* nodep) {
5329 // TREEOPV("AstNot {$lhsp.castGt, $lhsp.width1}", "AstLte {$lhsp->castGt()->lhsp(),$lhsp->castGt()->rhsp()}")
5330
2/2
✓ Branch 0 taken 391576 times.
✓ Branch 1 taken 73573 times.
465149 if (m_doV && VN_IS(nodep->lhsp(),Gt) && nodep->lhsp()->width1()) {
5331
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 35 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
35 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstNot $lhsp.castGt, $lhsp.width1 , AstLte $lhsp->castGt()->lhsp(),$lhsp->castGt()->rhsp() )\n");
5332 AstNodeExpr* arg1p = VN_CAST(nodep->lhsp(),Gt)->lhsp()->unlinkFrBack();
5333 AstNodeExpr* arg2p = VN_CAST(nodep->lhsp(),Gt)->rhsp()->unlinkFrBack();
5334
1/2
✓ Branch 2 taken 35 times.
✗ Branch 3 not taken.
35 AstNodeExpr* newp = new AstLte(nodep->fileline(), arg1p, arg2p);
5335 35 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
5336 35 return true;
5337 }
5338 return false;
5339 }
5340 // Generated by astgen
5341 465114 bool match_Not_12(AstNot* nodep) {
5342 // TREEOPV("AstNot {$lhsp.castGtS, $lhsp.width1}", "AstLteS{$lhsp->castGtS()->lhsp(),$lhsp->castGtS()->rhsp()}")
5343
2/2
✓ Branch 0 taken 391541 times.
✓ Branch 1 taken 73573 times.
465114 if (m_doV && VN_IS(nodep->lhsp(),GtS) && nodep->lhsp()->width1()) {
5344
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
3 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstNot $lhsp.castGtS, $lhsp.width1 , AstLteS $lhsp->castGtS()->lhsp(),$lhsp->castGtS()->rhsp() )\n");
5345 AstNodeExpr* arg1p = VN_CAST(nodep->lhsp(),GtS)->lhsp()->unlinkFrBack();
5346 AstNodeExpr* arg2p = VN_CAST(nodep->lhsp(),GtS)->rhsp()->unlinkFrBack();
5347
1/2
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
3 AstNodeExpr* newp = new AstLteS(nodep->fileline(), arg1p, arg2p);
5348 3 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
5349 3 return true;
5350 }
5351 return false;
5352 }
5353 // Generated by astgen
5354 465111 bool match_Not_13(AstNot* nodep) {
5355 // TREEOPV("AstNot {$lhsp.castGte, $lhsp.width1}", "AstLt {$lhsp->castGte()->lhsp(),$lhsp->castGte()->rhsp()}")
5356
2/2
✓ Branch 0 taken 391538 times.
✓ Branch 1 taken 73573 times.
465111 if (m_doV && VN_IS(nodep->lhsp(),Gte) && nodep->lhsp()->width1()) {
5357
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 38 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
38 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstNot $lhsp.castGte, $lhsp.width1 , AstLt $lhsp->castGte()->lhsp(),$lhsp->castGte()->rhsp() )\n");
5358 AstNodeExpr* arg1p = VN_CAST(nodep->lhsp(),Gte)->lhsp()->unlinkFrBack();
5359 AstNodeExpr* arg2p = VN_CAST(nodep->lhsp(),Gte)->rhsp()->unlinkFrBack();
5360
1/2
✓ Branch 2 taken 38 times.
✗ Branch 3 not taken.
38 AstNodeExpr* newp = new AstLt(nodep->fileline(), arg1p, arg2p);
5361 38 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
5362 38 return true;
5363 }
5364 return false;
5365 }
5366 // Generated by astgen
5367 465073 bool match_Not_14(AstNot* nodep) {
5368 // TREEOPV("AstNot {$lhsp.castGteS, $lhsp.width1}", "AstLtS {$lhsp->castGteS()->lhsp(),$lhsp->castGteS()->rhsp()}")
5369
2/2
✓ Branch 0 taken 391500 times.
✓ Branch 1 taken 73573 times.
465073 if (m_doV && VN_IS(nodep->lhsp(),GteS) && nodep->lhsp()->width1()) {
5370
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
7 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstNot $lhsp.castGteS, $lhsp.width1 , AstLtS $lhsp->castGteS()->lhsp(),$lhsp->castGteS()->rhsp() )\n");
5371 AstNodeExpr* arg1p = VN_CAST(nodep->lhsp(),GteS)->lhsp()->unlinkFrBack();
5372 AstNodeExpr* arg2p = VN_CAST(nodep->lhsp(),GteS)->rhsp()->unlinkFrBack();
5373
1/2
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
7 AstNodeExpr* newp = new AstLtS(nodep->fileline(), arg1p, arg2p);
5374 7 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
5375 7 return true;
5376 }
5377 return false;
5378 }
5379 // Generated by astgen
5380 bool match_OneHot_0(AstOneHot* nodep) {
5381 // TREEOPV("AstOneHot{$lhsp.width1}", "replaceWLhs(nodep)")
5382 if (m_doV && nodep->lhsp()->width1()) {
5383 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstOneHot $lhsp.width1 , replaceWLhs(nodep) )\n");
5384 replaceWLhs(nodep);
5385 return true;
5386 }
5387 return false;
5388 }
5389 // Generated by astgen
5390 bool match_OneHot0_0(AstOneHot0* nodep) {
5391 // TREEOPV("AstOneHot0{$lhsp.width1}", "replaceNum(nodep,1)")
5392 if (m_doV && nodep->lhsp()->width1()) {
5393 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstOneHot0 $lhsp.width1 , replaceNum(nodep,1) )\n");
5394 replaceNum(nodep,1);
5395 return true;
5396 }
5397 return false;
5398 }
5399 // Generated by astgen
5400 595336 bool match_Or_0(AstOr* nodep) {
5401 // TREEOP ("AstOr {$lhsp.isZero, $rhsp}", "replaceWRhs(nodep)")
5402
4/4
✓ Branch 0 taken 591532 times.
✓ Branch 1 taken 3804 times.
✓ Branch 3 taken 515918 times.
✓ Branch 4 taken 75614 times.
595336 if (m_doNConst && nodep->lhsp()->isZero()) {
5403
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 75614 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
75614 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstOr $lhsp.isZero, $rhsp , replaceWRhs(nodep) )\n");
5404 replaceWRhs(nodep);
5405 75614 return true;
5406 }
5407 return false;
5408 }
5409 // Generated by astgen
5410 519722 bool match_Or_1(AstOr* nodep) {
5411 // TREEOP ("AstOr {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)")
5412
3/4
✓ Branch 0 taken 515918 times.
✓ Branch 1 taken 3804 times.
✓ Branch 3 taken 515918 times.
✗ Branch 4 not taken.
519722 if (m_doNConst && nodep->rhsp()->isZero()) {
5413 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstOr $lhsp, $rhsp.isZero , replaceWLhs(nodep) )\n");
5414 replaceWLhs(nodep);
5415 return true;
5416 }
5417 return false;
5418 }
5419 // Generated by astgen
5420 519722 bool match_Or_2(AstOr* nodep) {
5421 // TREEOP ("AstOr {$lhsp.isAllOnes, $rhsp, $rhsp.isPure}", "replaceWLhs(nodep)")
5422
5/6
✓ Branch 0 taken 515918 times.
✓ Branch 1 taken 3804 times.
✓ Branch 3 taken 514617 times.
✓ Branch 4 taken 1301 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 1301 times.
519722 if (m_doNConst && nodep->lhsp()->isAllOnes() && nodep->rhsp()->isPure()) {
5423
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 1301 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
1301 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstOr $lhsp.isAllOnes, $rhsp, $rhsp.isPure , replaceWLhs(nodep) )\n");
5424 replaceWLhs(nodep);
5425 1301 return true;
5426 }
5427 return false;
5428 }
5429 // Generated by astgen
5430 518421 bool match_Or_3(AstOr* nodep) {
5431 // TREEOP ("AstOr {$lhsp, $rhsp.isAllOnes, $lhsp.isPure}", "replaceWRhs(nodep)")
5432
3/6
✓ Branch 0 taken 514617 times.
✓ Branch 1 taken 3804 times.
✓ Branch 3 taken 514617 times.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
518421 if (m_doNConst && nodep->rhsp()->isAllOnes() && nodep->lhsp()->isPure()) {
5433 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstOr $lhsp, $rhsp.isAllOnes, $lhsp.isPure , replaceWRhs(nodep) )\n");
5434 replaceWRhs(nodep);
5435 return true;
5436 }
5437 return false;
5438 }
5439 // Generated by astgen
5440 518421 bool match_Or_4(AstOr* nodep) {
5441 // TREEOP ("AstOr {operandsSame($lhsp,,$rhsp)}", "replaceWLhs(nodep)")
5442
4/4
✓ Branch 0 taken 514617 times.
✓ Branch 1 taken 3804 times.
✓ Branch 3 taken 514494 times.
✓ Branch 4 taken 123 times.
518421 if (m_doNConst && operandsSame(nodep->lhsp(),nodep->rhsp())) {
5443
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 123 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
123 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstOr operandsSame($lhsp,,$rhsp) , replaceWLhs(nodep) )\n");
5444 replaceWLhs(nodep);
5445 123 return true;
5446 }
5447 return false;
5448 }
5449 // Generated by astgen
5450 518298 bool match_Or_5(AstOr* nodep) {
5451 // TREEOP ("AstOr {$lhsp.castAnd,$rhsp.castAnd,operandAndOrSame(nodep)}", "replaceAndOr(nodep)")
5452
4/4
✓ Branch 0 taken 514494 times.
✓ Branch 1 taken 3804 times.
✓ Branch 3 taken 20083 times.
✓ Branch 4 taken 634 times.
539015 if (m_doNConst && VN_IS(nodep->lhsp(),And) && VN_IS(nodep->rhsp(),And) && operandAndOrSame(nodep)) {
5453
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 634 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
634 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstOr $lhsp.castAnd,$rhsp.castAnd,operandAndOrSame(nodep) , replaceAndOr(nodep) )\n");
5454 634 replaceAndOr(nodep);
5455 634 return true;
5456 }
5457 return false;
5458 }
5459 // Generated by astgen
5460 517664 bool match_Or_6(AstOr* nodep) {
5461 // TREEOP ("AstOr {matchOrAndNot(nodep)}", "DONE")
5462
3/4
✓ Branch 0 taken 513860 times.
✓ Branch 1 taken 3804 times.
✓ Branch 3 taken 513860 times.
✗ Branch 4 not taken.
517664 if (m_doNConst && matchOrAndNot(nodep)) {
5463 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstOr matchOrAndNot(nodep) , DONE )\n");
5464
5465 return true;
5466 }
5467 return false;
5468 }
5469 // Generated by astgen
5470 517664 bool match_Or_7(AstOr* nodep) {
5471 // TREEOP ("AstOr {operandShiftSame(nodep)}", "replaceShiftSame(nodep)")
5472
4/4
✓ Branch 0 taken 513860 times.
✓ Branch 1 taken 3804 times.
✓ Branch 3 taken 513486 times.
✓ Branch 4 taken 374 times.
517664 if (m_doNConst && operandShiftSame(nodep)) {
5473
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 374 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
374 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstOr operandShiftSame(nodep) , replaceShiftSame(nodep) )\n");
5474 374 replaceShiftSame(nodep);
5475 374 return true;
5476 }
5477 return false;
5478 }
5479 // Generated by astgen
5480 517290 bool match_Or_8(AstOr* nodep) {
5481 // TREEOPC("AstOr {matchBitOpTree(nodep)}", "DONE")
5482
4/4
✓ Branch 0 taken 403149 times.
✓ Branch 1 taken 114141 times.
✓ Branch 3 taken 402877 times.
✓ Branch 4 taken 272 times.
517290 if (m_doCpp && matchBitOpTree(nodep)) {
5483
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 272 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
272 UINFO(7, cvtToHex(nodep) << " TREEOPC( AstOr matchBitOpTree(nodep) , DONE )\n");
5484
5485 272 return true;
5486 }
5487 return false;
5488 }
5489 // Generated by astgen
5490 bool match_Pow_0(AstPow* nodep) {
5491 // TREEOP ("AstPow {$rhsp.isZero}", "replaceNum(nodep, 1)")
5492 if (m_doNConst && nodep->rhsp()->isZero()) {
5493 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstPow $rhsp.isZero , replaceNum(nodep, 1) )\n");
5494 replaceNum(nodep, 1);
5495 return true;
5496 }
5497 return false;
5498 }
5499 // Generated by astgen
5500 bool match_Pow_1(AstPow* nodep) {
5501 // TREEOP ("AstPow {operandIsTwo($lhsp), !$rhsp.isZero}", "replacePowShift(nodep)")
5502 if (m_doNConst && operandIsTwo(nodep->lhsp()) && !nodep->rhsp()->isZero()) {
5503 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstPow operandIsTwo($lhsp), !$rhsp.isZero , replacePowShift(nodep) )\n");
5504 replacePowShift(nodep);
5505 return true;
5506 }
5507 return false;
5508 }
5509 // Generated by astgen
5510 bool match_PowSS_0(AstPowSS* nodep) {
5511 // TREEOP ("AstPowSS {$rhsp.isZero}", "replaceNum(nodep, 1)")
5512 if (m_doNConst && nodep->rhsp()->isZero()) {
5513 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstPowSS $rhsp.isZero , replaceNum(nodep, 1) )\n");
5514 replaceNum(nodep, 1);
5515 return true;
5516 }
5517 return false;
5518 }
5519 // Generated by astgen
5520 bool match_PowSU_0(AstPowSU* nodep) {
5521 // TREEOP ("AstPowSU {$rhsp.isZero}", "replaceNum(nodep, 1)")
5522 if (m_doNConst && nodep->rhsp()->isZero()) {
5523 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstPowSU $rhsp.isZero , replaceNum(nodep, 1) )\n");
5524 replaceNum(nodep, 1);
5525 return true;
5526 }
5527 return false;
5528 }
5529 // Generated by astgen
5530 bool match_PowUS_0(AstPowUS* nodep) {
5531 // TREEOP ("AstPowUS {$rhsp.isZero}", "replaceNum(nodep, 1)")
5532 if (m_doNConst && nodep->rhsp()->isZero()) {
5533 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstPowUS $rhsp.isZero , replaceNum(nodep, 1) )\n");
5534 replaceNum(nodep, 1);
5535 return true;
5536 }
5537 return false;
5538 }
5539 // Generated by astgen
5540 bool match_PutcN_0(AstPutcN* nodep) {
5541 // TREEOPA("AstPutcN{$lhsp.castConst, $rhsp.castConst, $thsp.castConst}", "replaceConst(nodep)")
5542 if (VN_IS(nodep->lhsp(),Const) && VN_IS(nodep->rhsp(),Const) && VN_IS(nodep->thsp(),Const)) {
5543 UINFO(7, cvtToHex(nodep) << " TREEOPA( AstPutcN $lhsp.castConst, $rhsp.castConst, $thsp.castConst , replaceConst(nodep) )\n");
5544 replaceConst(nodep);
5545 return true;
5546 }
5547 return false;
5548 }
5549 // Generated by astgen
5550 126619 bool match_RedAnd_0(AstRedAnd* nodep) {
5551 // TREEOPV("AstRedAnd{$lhsp, $lhsp.width1}", "replaceWLhs(nodep)")
5552
2/2
✓ Branch 0 taken 113511 times.
✓ Branch 1 taken 13108 times.
126619 if (m_doV && nodep->lhsp()->width1()) {
5553
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 2498 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
2498 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstRedAnd $lhsp, $lhsp.width1 , replaceWLhs(nodep) )\n");
5554 replaceWLhs(nodep);
5555 2498 return true;
5556 }
5557 return false;
5558 }
5559 // Generated by astgen
5560 124121 bool match_RedAnd_1(AstRedAnd* nodep) {
5561 // TREEOPV("AstRedAnd{$lhsp.castConcat}", "AstAnd{AstRedAnd{$lhsp->castConcat()->lhsp()}, AstRedAnd{$lhsp->castConcat()->rhsp()}}")
5562
2/2
✓ Branch 0 taken 111013 times.
✓ Branch 1 taken 13108 times.
124121 if (m_doV && VN_IS(nodep->lhsp(),Concat)) {
5563
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 680 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
680 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstRedAnd $lhsp.castConcat , AstAnd AstRedAnd $lhsp->castConcat()->lhsp() , AstRedAnd $lhsp->castConcat()->rhsp() )\n");
5564 AstNodeExpr* arg1p = VN_CAST(nodep->lhsp(),Concat)->lhsp()->unlinkFrBack();
5565 AstNodeExpr* arg2p = VN_CAST(nodep->lhsp(),Concat)->rhsp()->unlinkFrBack();
5566
5/10
✓ Branch 2 taken 680 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 680 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 680 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 680 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 680 times.
✗ Branch 15 not taken.
680 AstNodeExpr* newp = new AstAnd(nodep->fileline(), new AstRedAnd(nodep->fileline(), arg1p), new AstRedAnd(nodep->fileline(), arg2p));
5567 680 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
5568 680 return true;
5569 }
5570 return false;
5571 }
5572 // Generated by astgen
5573 123441 bool match_RedAnd_2(AstRedAnd* nodep) {
5574 // TREEOPV("AstRedAnd{$lhsp.castExtend, $lhsp->width() > VN_AS($lhsp,,Extend)->lhsp()->width()}", "replaceZero(nodep)")
5575
3/4
✓ Branch 0 taken 110333 times.
✓ Branch 1 taken 13108 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 683 times.
124807 if (m_doV && VN_IS(nodep->lhsp(),Extend) && nodep->lhsp()->width() > VN_AS(nodep->lhsp(),Extend)->lhsp()->width()) {
5576
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 683 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
683 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstRedAnd $lhsp.castExtend, $lhsp->width() > VN_AS($lhsp,,Extend)->lhsp()->width() , replaceZero(nodep) )\n");
5577 replaceZero(nodep);
5578 683 return true;
5579 }
5580 return false;
5581 }
5582 // Generated by astgen
5583 1007405 bool match_RedOr_0(AstRedOr* nodep) {
5584 // TREEOPV("AstRedOr {$lhsp, $lhsp.width1}", "replaceWLhs(nodep)")
5585
2/2
✓ Branch 0 taken 914064 times.
✓ Branch 1 taken 93341 times.
1007405 if (m_doV && nodep->lhsp()->width1()) {
5586
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 7135 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
7135 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstRedOr $lhsp, $lhsp.width1 , replaceWLhs(nodep) )\n");
5587 replaceWLhs(nodep);
5588 7135 return true;
5589 }
5590 return false;
5591 }
5592 // Generated by astgen
5593 1000270 bool match_RedOr_1(AstRedOr* nodep) {
5594 // TREEOPV("AstRedOr {$lhsp.castConcat}", "AstOr {AstRedOr {$lhsp->castConcat()->lhsp()}, AstRedOr {$lhsp->castConcat()->rhsp()}}")
5595
2/2
✓ Branch 0 taken 906929 times.
✓ Branch 1 taken 93341 times.
1000270 if (m_doV && VN_IS(nodep->lhsp(),Concat)) {
5596
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 6135 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
6135 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstRedOr $lhsp.castConcat , AstOr AstRedOr $lhsp->castConcat()->lhsp() , AstRedOr $lhsp->castConcat()->rhsp() )\n");
5597 AstNodeExpr* arg1p = VN_CAST(nodep->lhsp(),Concat)->lhsp()->unlinkFrBack();
5598 AstNodeExpr* arg2p = VN_CAST(nodep->lhsp(),Concat)->rhsp()->unlinkFrBack();
5599
5/10
✓ Branch 2 taken 6135 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 6135 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 6135 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 6135 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 6135 times.
✗ Branch 15 not taken.
6135 AstNodeExpr* newp = new AstOr(nodep->fileline(), new AstRedOr(nodep->fileline(), arg1p), new AstRedOr(nodep->fileline(), arg2p));
5600 6135 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
5601 6135 return true;
5602 }
5603 return false;
5604 }
5605 // Generated by astgen
5606 994135 bool match_RedOr_2(AstRedOr* nodep) {
5607 // TREEOPV("AstRedOr {$lhsp.castExtend}", "AstRedOr {$lhsp->castExtend()->lhsp()}")
5608
2/2
✓ Branch 0 taken 900794 times.
✓ Branch 1 taken 93341 times.
994135 if (m_doV && VN_IS(nodep->lhsp(),Extend)) {
5609
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 6085 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
6085 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstRedOr $lhsp.castExtend , AstRedOr $lhsp->castExtend()->lhsp() )\n");
5610 AstNodeExpr* arg1p = VN_CAST(nodep->lhsp(),Extend)->lhsp()->unlinkFrBack();
5611
1/2
✓ Branch 2 taken 6085 times.
✗ Branch 3 not taken.
6085 AstNodeExpr* newp = new AstRedOr(nodep->fileline(), arg1p);
5612 6085 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
5613 6085 return true;
5614 }
5615 return false;
5616 }
5617 // Generated by astgen
5618 217979 bool match_RedXor_0(AstRedXor* nodep) {
5619 // TREEOPV("AstRedXor{$lhsp, $lhsp.width1}", "replaceWLhs(nodep)")
5620
2/2
✓ Branch 0 taken 177390 times.
✓ Branch 1 taken 40589 times.
217979 if (m_doV && nodep->lhsp()->width1()) {
5621
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 4211 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
4211 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstRedXor $lhsp, $lhsp.width1 , replaceWLhs(nodep) )\n");
5622 replaceWLhs(nodep);
5623 4211 return true;
5624 }
5625 return false;
5626 }
5627 // Generated by astgen
5628 213768 bool match_RedXor_1(AstRedXor* nodep) {
5629 // TREEOPV("AstRedXor{$lhsp.castConcat}", "AstXor{AstRedXor{$lhsp->castConcat()->lhsp()}, AstRedXor{$lhsp->castConcat()->rhsp()}}")
5630
2/2
✓ Branch 0 taken 173179 times.
✓ Branch 1 taken 40589 times.
213768 if (m_doV && VN_IS(nodep->lhsp(),Concat)) {
5631
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 999 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
999 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstRedXor $lhsp.castConcat , AstXor AstRedXor $lhsp->castConcat()->lhsp() , AstRedXor $lhsp->castConcat()->rhsp() )\n");
5632 AstNodeExpr* arg1p = VN_CAST(nodep->lhsp(),Concat)->lhsp()->unlinkFrBack();
5633 AstNodeExpr* arg2p = VN_CAST(nodep->lhsp(),Concat)->rhsp()->unlinkFrBack();
5634
5/10
✓ Branch 2 taken 999 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 999 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 999 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 999 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 999 times.
✗ Branch 15 not taken.
999 AstNodeExpr* newp = new AstXor(nodep->fileline(), new AstRedXor(nodep->fileline(), arg1p), new AstRedXor(nodep->fileline(), arg2p));
5635 999 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
5636 999 return true;
5637 }
5638 return false;
5639 }
5640 // Generated by astgen
5641 212769 bool match_RedXor_2(AstRedXor* nodep) {
5642 // TREEOPV("AstRedXor{$lhsp.castExtend}", "AstRedXor{$lhsp->castExtend()->lhsp()}")
5643
2/2
✓ Branch 0 taken 172180 times.
✓ Branch 1 taken 40589 times.
212769 if (m_doV && VN_IS(nodep->lhsp(),Extend)) {
5644
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 1025 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
1025 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstRedXor $lhsp.castExtend , AstRedXor $lhsp->castExtend()->lhsp() )\n");
5645 AstNodeExpr* arg1p = VN_CAST(nodep->lhsp(),Extend)->lhsp()->unlinkFrBack();
5646
1/2
✓ Branch 2 taken 1025 times.
✗ Branch 3 not taken.
1025 AstNodeExpr* newp = new AstRedXor(nodep->fileline(), arg1p);
5647 1025 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
5648 1025 return true;
5649 }
5650 return false;
5651 }
5652 // Generated by astgen
5653 211744 bool match_RedXor_3(AstRedXor* nodep) {
5654 // TREEOP ("AstRedXor{$lhsp.castXor, VN_IS(VN_AS($lhsp,,Xor)->lhsp(),,Const)}", "AstXor{AstRedXor{$lhsp->castXor()->lhsp()}, AstRedXor{$lhsp->castXor()->rhsp()}}")
5655
2/2
✓ Branch 0 taken 192526 times.
✓ Branch 1 taken 19218 times.
213013 if (m_doNConst && VN_IS(nodep->lhsp(),Xor) && VN_IS(VN_AS(nodep->lhsp(),Xor)->lhsp(),Const)) {
5656
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 29 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
29 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstRedXor $lhsp.castXor, VN_IS(VN_AS($lhsp,,Xor)->lhsp(),,Const) , AstXor AstRedXor $lhsp->castXor()->lhsp() , AstRedXor $lhsp->castXor()->rhsp() )\n");
5657 AstNodeExpr* arg1p = VN_CAST(nodep->lhsp(),Xor)->lhsp()->unlinkFrBack();
5658 AstNodeExpr* arg2p = VN_CAST(nodep->lhsp(),Xor)->rhsp()->unlinkFrBack();
5659
5/10
✓ Branch 2 taken 29 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 29 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 29 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 29 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 29 times.
✗ Branch 15 not taken.
29 AstNodeExpr* newp = new AstXor(nodep->fileline(), new AstRedXor(nodep->fileline(), arg1p), new AstRedXor(nodep->fileline(), arg2p));
5660 29 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
5661 29 return true;
5662 }
5663 return false;
5664 }
5665 // Generated by astgen
5666 97022 bool match_Replicate_0(AstReplicate* nodep) {
5667 // TREEOPV("AstReplicate{$srcp, $countp.isOne, $srcp->width()==nodep->width()}", "replaceWLhs(nodep)")
5668
5/6
✓ Branch 0 taken 49619 times.
✓ Branch 1 taken 47403 times.
✓ Branch 3 taken 3919 times.
✓ Branch 4 taken 45700 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 45700 times.
142722 if (m_doV && nodep->countp()->isOne() && nodep->srcp()->width()==nodep->width()) {
5669
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 45700 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
45700 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstReplicate $srcp, $countp.isOne, $srcp->width()==nodep->width() , replaceWLhs(nodep) )\n");
5670 replaceWLhs(nodep);
5671 45700 return true;
5672 }
5673 return false;
5674 }
5675 // Generated by astgen
5676 51322 bool match_Replicate_1(AstReplicate* nodep) {
5677 // TREEOPV("AstReplicate{$srcp.castReplicate, operandRepRep(nodep)}", "DONE")
5678
2/4
✓ Branch 0 taken 3919 times.
✓ Branch 1 taken 47403 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
51322 if (m_doV && VN_IS(nodep->srcp(),Replicate) && operandRepRep(nodep)) {
5679 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstReplicate $srcp.castReplicate, operandRepRep(nodep) , DONE )\n");
5680
5681 return true;
5682 }
5683 return false;
5684 }
5685 // Generated by astgen
5686 bool match_ReplicateN_0(AstReplicateN* nodep) {
5687 // TREEOPV("AstReplicateN{$lhsp, $rhsp.isOne, $lhsp->width()==nodep->width()}", "replaceWLhs(nodep)")
5688 if (m_doV && nodep->rhsp()->isOne() && nodep->lhsp()->width()==nodep->width()) {
5689 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstReplicateN $lhsp, $rhsp.isOne, $lhsp->width()==nodep->width() , replaceWLhs(nodep) )\n");
5690 replaceWLhs(nodep);
5691 return true;
5692 }
5693 return false;
5694 }
5695 // Generated by astgen
5696 1344563 bool match_Sel_0(AstSel* nodep) {
5697 // TREEOP1("AstSel{warnSelect(nodep)}", "NEVER")
5698
3/4
✓ Branch 0 taken 1233609 times.
✓ Branch 1 taken 110954 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1233609 times.
1344563 if (m_doNConst && warnSelect(nodep)) {
5699 UINFO(7, cvtToHex(nodep) << " TREEOP1( AstSel warnSelect(nodep) , NEVER )\n");
5700 nodep->v3fatalSrc("Executing transform that was NEVERed");
5701 return true;
5702 }
5703 return false;
5704 }
5705 // Generated by astgen
5706 1344563 bool match_Sel_1(AstSel* nodep) {
5707 // TREEOPV("AstSel{matchSelRand(nodep)}", "DONE")
5708
3/4
✓ Branch 0 taken 1233609 times.
✓ Branch 1 taken 110954 times.
✓ Branch 3 taken 1233609 times.
✗ Branch 4 not taken.
1344563 if (m_doV && matchSelRand(nodep)) {
5709 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstSel matchSelRand(nodep) , DONE )\n");
5710
5711 return true;
5712 }
5713 return false;
5714 }
5715 // Generated by astgen
5716 1344563 bool match_Sel_2(AstSel* nodep) {
5717 // TREEOPV("AstSel{operandSelExtend(nodep)}", "DONE")
5718
4/4
✓ Branch 0 taken 1233609 times.
✓ Branch 1 taken 110954 times.
✓ Branch 3 taken 1232892 times.
✓ Branch 4 taken 717 times.
1344563 if (m_doV && operandSelExtend(nodep)) {
5719
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 717 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
717 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstSel operandSelExtend(nodep) , DONE )\n");
5720
5721 717 return true;
5722 }
5723 return false;
5724 }
5725 // Generated by astgen
5726 1343846 bool match_Sel_3(AstSel* nodep) {
5727 // TREEOPV("AstSel{operandSelFull(nodep)}", "replaceWChild(nodep, nodep->fromp())")
5728
4/4
✓ Branch 0 taken 1232892 times.
✓ Branch 1 taken 110954 times.
✓ Branch 3 taken 1223265 times.
✓ Branch 4 taken 9627 times.
1343846 if (m_doV && operandSelFull(nodep)) {
5729
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 9627 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
9627 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstSel operandSelFull(nodep) , replaceWChild(nodep, nodep->fromp()) )\n");
5730 9627 replaceWChild(nodep, nodep->fromp());
5731 9627 return true;
5732 }
5733 return false;
5734 }
5735 // Generated by astgen
5736 1334219 bool match_Sel_4(AstSel* nodep) {
5737 // TREEOPV("AstSel{$fromp.castSel}", "replaceSelSel(nodep)")
5738
2/2
✓ Branch 0 taken 1223265 times.
✓ Branch 1 taken 110954 times.
1334219 if (m_doV && VN_IS(nodep->fromp(),Sel)) {
5739
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 11029 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
11029 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstSel $fromp.castSel , replaceSelSel(nodep) )\n");
5740 11029 replaceSelSel(nodep);
5741 11029 return true;
5742 }
5743 return false;
5744 }
5745 // Generated by astgen
5746 1323190 bool match_Sel_5(AstSel* nodep) {
5747 // TREEOPV("AstSel{$fromp.castAdd, operandSelBiLower(nodep)}", "DONE")
5748
4/4
✓ Branch 0 taken 1212236 times.
✓ Branch 1 taken 110954 times.
✓ Branch 3 taken 55 times.
✓ Branch 4 taken 538 times.
1323783 if (m_doV && VN_IS(nodep->fromp(),Add) && operandSelBiLower(nodep)) {
5749
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 538 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
538 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstSel $fromp.castAdd, operandSelBiLower(nodep) , DONE )\n");
5750
5751 538 return true;
5752 }
5753 return false;
5754 }
5755 // Generated by astgen
5756 1322652 bool match_Sel_6(AstSel* nodep) {
5757 // TREEOPV("AstSel{$fromp.castAnd, operandSelBiLower(nodep)}", "DONE")
5758
4/4
✓ Branch 0 taken 1211698 times.
✓ Branch 1 taken 110954 times.
✓ Branch 3 taken 9 times.
✓ Branch 4 taken 548 times.
1323209 if (m_doV && VN_IS(nodep->fromp(),And) && operandSelBiLower(nodep)) {
5759
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 548 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
548 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstSel $fromp.castAnd, operandSelBiLower(nodep) , DONE )\n");
5760
5761 548 return true;
5762 }
5763 return false;
5764 }
5765 // Generated by astgen
5766 1322104 bool match_Sel_7(AstSel* nodep) {
5767 // TREEOPV("AstSel{$fromp.castOr, operandSelBiLower(nodep)}", "DONE")
5768
4/4
✓ Branch 0 taken 1211150 times.
✓ Branch 1 taken 110954 times.
✓ Branch 3 taken 21 times.
✓ Branch 4 taken 539 times.
1322664 if (m_doV && VN_IS(nodep->fromp(),Or) && operandSelBiLower(nodep)) {
5769
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 539 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
539 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstSel $fromp.castOr, operandSelBiLower(nodep) , DONE )\n");
5770
5771 539 return true;
5772 }
5773 return false;
5774 }
5775 // Generated by astgen
5776 1321565 bool match_Sel_8(AstSel* nodep) {
5777 // TREEOPV("AstSel{$fromp.castSub, operandSelBiLower(nodep)}", "DONE")
5778
4/4
✓ Branch 0 taken 1210611 times.
✓ Branch 1 taken 110954 times.
✓ Branch 3 taken 41 times.
✓ Branch 4 taken 494 times.
1322100 if (m_doV && VN_IS(nodep->fromp(),Sub) && operandSelBiLower(nodep)) {
5779
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 494 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
494 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstSel $fromp.castSub, operandSelBiLower(nodep) , DONE )\n");
5780
5781 494 return true;
5782 }
5783 return false;
5784 }
5785 // Generated by astgen
5786 1321071 bool match_Sel_9(AstSel* nodep) {
5787 // TREEOPV("AstSel{$fromp.castXor, operandSelBiLower(nodep)}", "DONE")
5788
4/4
✓ Branch 0 taken 1210117 times.
✓ Branch 1 taken 110954 times.
✓ Branch 3 taken 28 times.
✓ Branch 4 taken 1641 times.
1322740 if (m_doV && VN_IS(nodep->fromp(),Xor) && operandSelBiLower(nodep)) {
5789
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 1641 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
1641 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstSel $fromp.castXor, operandSelBiLower(nodep) , DONE )\n");
5790
5791 1641 return true;
5792 }
5793 return false;
5794 }
5795 // Generated by astgen
5796 1319430 bool match_Sel_10(AstSel* nodep) {
5797 // TREEOPV("AstSel{$fromp.castShiftR, operandSelShiftLower(nodep)}", "DONE")
5798
4/4
✓ Branch 0 taken 1208476 times.
✓ Branch 1 taken 110954 times.
✓ Branch 3 taken 5402 times.
✓ Branch 4 taken 14 times.
1324846 if (m_doV && VN_IS(nodep->fromp(),ShiftR) && operandSelShiftLower(nodep)) {
5799
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
14 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstSel $fromp.castShiftR, operandSelShiftLower(nodep) , DONE )\n");
5800
5801 14 return true;
5802 }
5803 return false;
5804 }
5805 // Generated by astgen
5806
1/2
✓ Branch 0 taken 1319416 times.
✗ Branch 1 not taken.
1319416 bool match_Sel_11(AstSel* nodep) {
5807 // TREEOPA("AstSel{$fromp.castConst, $lsbp.castConst, $widthp.castConst, }", "replaceConst(nodep)")
5808 if (VN_IS(nodep->fromp(),Const) && VN_IS(nodep->lsbp(),Const) && VN_IS(nodep->widthp(),Const)) {
5809
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 6184 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
6184 UINFO(7, cvtToHex(nodep) << " TREEOPA( AstSel $fromp.castConst, $lsbp.castConst, $widthp.castConst, , replaceConst(nodep) )\n");
5810 6184 replaceConst(nodep);
5811 6184 return true;
5812 }
5813 return false;
5814 }
5815 // Generated by astgen
5816 1313232 bool match_Sel_12(AstSel* nodep) {
5817 // TREEOPV("AstSel{$fromp.castConcat, $lsbp.castConst, $widthp.castConst, }", "replaceSelConcat(nodep)")
5818
2/2
✓ Branch 0 taken 1203030 times.
✓ Branch 1 taken 110202 times.
1313232 if (m_doV && VN_IS(nodep->fromp(),Concat) && VN_IS(nodep->lsbp(),Const) && VN_IS(nodep->widthp(),Const)) {
5819
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 14302 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
14302 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstSel $fromp.castConcat, $lsbp.castConst, $widthp.castConst, , replaceSelConcat(nodep) )\n");
5820 14302 replaceSelConcat(nodep);
5821 14302 return true;
5822 }
5823 return false;
5824 }
5825 // Generated by astgen
5826 1298930 bool match_Sel_13(AstSel* nodep) {
5827 // TREEOPV("AstSel{$fromp.castReplicate, $lsbp.castConst, $widthp.castConst, operandSelReplicate(nodep) }", "DONE")
5828
4/4
✓ Branch 0 taken 1188728 times.
✓ Branch 1 taken 110202 times.
✓ Branch 3 taken 50 times.
✓ Branch 4 taken 16 times.
1298996 if (m_doV && VN_IS(nodep->fromp(),Replicate) && VN_IS(nodep->lsbp(),Const) && VN_IS(nodep->widthp(),Const) && operandSelReplicate(nodep) ) {
5829
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 16 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
16 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstSel $fromp.castReplicate, $lsbp.castConst, $widthp.castConst, operandSelReplicate(nodep) , DONE )\n");
5830
5831 16 return true;
5832 }
5833 return false;
5834 }
5835 // Generated by astgen
5836 1298914 bool match_Sel_14(AstSel* nodep) {
5837 // TREEOPV("AstSel{$fromp.castBufIf1}", "replaceSelIntoBiop(nodep)")
5838
2/2
✓ Branch 0 taken 1188712 times.
✓ Branch 1 taken 110202 times.
1298914 if (m_doV && VN_IS(nodep->fromp(),BufIf1)) {
5839 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstSel $fromp.castBufIf1 , replaceSelIntoBiop(nodep) )\n");
5840 replaceSelIntoBiop(nodep);
5841 return true;
5842 }
5843 return false;
5844 }
5845 // Generated by astgen
5846 1298914 bool match_Sel_15(AstSel* nodep) {
5847 // TREEOPV("AstSel{$fromp.castNot}", "replaceSelIntoUniop(nodep)")
5848
2/2
✓ Branch 0 taken 1188712 times.
✓ Branch 1 taken 110202 times.
1298914 if (m_doV && VN_IS(nodep->fromp(),Not)) {
5849
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 2003 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
2003 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstSel $fromp.castNot , replaceSelIntoUniop(nodep) )\n");
5850 2003 replaceSelIntoUniop(nodep);
5851 2003 return true;
5852 }
5853 return false;
5854 }
5855 // Generated by astgen
5856 1296911 bool match_Sel_16(AstSel* nodep) {
5857 // TREEOPV("AstSel{$fromp.castAnd,$lsbp.castConst}", "replaceSelIntoBiop(nodep)")
5858
2/2
✓ Branch 0 taken 1186709 times.
✓ Branch 1 taken 110202 times.
1296911 if (m_doV && VN_IS(nodep->fromp(),And) && VN_IS(nodep->lsbp(),Const)) {
5859
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
9 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstSel $fromp.castAnd,$lsbp.castConst , replaceSelIntoBiop(nodep) )\n");
5860 9 replaceSelIntoBiop(nodep);
5861 9 return true;
5862 }
5863 return false;
5864 }
5865 // Generated by astgen
5866 1296902 bool match_Sel_17(AstSel* nodep) {
5867 // TREEOPV("AstSel{$fromp.castOr,$lsbp.castConst}", "replaceSelIntoBiop(nodep)")
5868
2/2
✓ Branch 0 taken 1186700 times.
✓ Branch 1 taken 110202 times.
1296902 if (m_doV && VN_IS(nodep->fromp(),Or) && VN_IS(nodep->lsbp(),Const)) {
5869
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 21 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
21 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstSel $fromp.castOr,$lsbp.castConst , replaceSelIntoBiop(nodep) )\n");
5870 21 replaceSelIntoBiop(nodep);
5871 21 return true;
5872 }
5873 return false;
5874 }
5875 // Generated by astgen
5876 1296881 bool match_Sel_18(AstSel* nodep) {
5877 // TREEOPV("AstSel{$fromp.castXor,$lsbp.castConst}", "replaceSelIntoBiop(nodep)")
5878
2/2
✓ Branch 0 taken 1186679 times.
✓ Branch 1 taken 110202 times.
1296881 if (m_doV && VN_IS(nodep->fromp(),Xor) && VN_IS(nodep->lsbp(),Const)) {
5879
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
28 UINFO(7, cvtToHex(nodep) << " TREEOPV( AstSel $fromp.castXor,$lsbp.castConst , replaceSelIntoBiop(nodep) )\n");
5880 28 replaceSelIntoBiop(nodep);
5881 28 return true;
5882 }
5883 return false;
5884 }
5885 // Generated by astgen
5886 590211 bool match_ShiftL_0(AstShiftL* nodep) {
5887 // TREEOP ("AstShiftL {$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)")
5888
4/4
✓ Branch 0 taken 582385 times.
✓ Branch 1 taken 7826 times.
✓ Branch 3 taken 582143 times.
✓ Branch 4 taken 242 times.
590211 if (m_doNConst && nodep->lhsp()->isZero()) {
5889
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 242 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
242 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstShiftL $lhsp.isZero, $rhsp , replaceZeroChkPure(nodep,$rhsp) )\n");
5890 242 replaceZeroChkPure(nodep,nodep->rhsp());
5891 242 return true;
5892 }
5893 return false;
5894 }
5895 // Generated by astgen
5896 589969 bool match_ShiftL_1(AstShiftL* nodep) {
5897 // TREEOP ("AstShiftL {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)")
5898
4/4
✓ Branch 0 taken 582143 times.
✓ Branch 1 taken 7826 times.
✓ Branch 3 taken 581670 times.
✓ Branch 4 taken 473 times.
589969 if (m_doNConst && nodep->rhsp()->isZero()) {
5899
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 473 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
473 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstShiftL $lhsp, $rhsp.isZero , replaceWLhs(nodep) )\n");
5900 replaceWLhs(nodep);
5901 473 return true;
5902 }
5903 return false;
5904 }
5905 // Generated by astgen
5906 589496 bool match_ShiftL_2(AstShiftL* nodep) {
5907 // TREEOP ("AstShiftL {operandHugeShiftL(nodep)}", "replaceZero(nodep)")
5908
4/4
✓ Branch 0 taken 581670 times.
✓ Branch 1 taken 7826 times.
✓ Branch 3 taken 578626 times.
✓ Branch 4 taken 3044 times.
589496 if (m_doNConst && operandHugeShiftL(nodep)) {
5909
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 3044 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
3044 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstShiftL operandHugeShiftL(nodep) , replaceZero(nodep) )\n");
5910 replaceZero(nodep);
5911 3044 return true;
5912 }
5913 return false;
5914 }
5915 // Generated by astgen
5916 586452 bool match_ShiftL_3(AstShiftL* nodep) {
5917 // TREEOP ("AstShiftL{operandShiftOp(nodep)}", "replaceShiftOp(nodep)")
5918
4/4
✓ Branch 0 taken 578626 times.
✓ Branch 1 taken 7826 times.
✓ Branch 2 taken 23335 times.
✓ Branch 3 taken 555291 times.
586452 if (m_doNConst && operandShiftOp(nodep)) {
5919
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 23335 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
23335 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstShiftL operandShiftOp(nodep) , replaceShiftOp(nodep) )\n");
5920 23335 replaceShiftOp(nodep);
5921 23335 return true;
5922 }
5923 return false;
5924 }
5925 // Generated by astgen
5926 563117 bool match_ShiftL_4(AstShiftL* nodep) {
5927 // TREEOP ("AstShiftL{operandShiftShift(nodep)}", "replaceShiftShift(nodep)")
5928
4/4
✓ Branch 0 taken 555291 times.
✓ Branch 1 taken 7826 times.
✓ Branch 3 taken 543976 times.
✓ Branch 4 taken 11315 times.
563117 if (m_doNConst && operandShiftShift(nodep)) {
5929
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 11315 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
11315 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstShiftL operandShiftShift(nodep) , replaceShiftShift(nodep) )\n");
5930 11315 replaceShiftShift(nodep);
5931 11315 return true;
5932 }
5933 return false;
5934 }
5935 // Generated by astgen
5936 7861 bool match_ShiftLOvr_0(AstShiftLOvr* nodep) {
5937 // TREEOP ("AstShiftLOvr {$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)")
5938
3/4
✓ Branch 0 taken 7861 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 7856 times.
✓ Branch 4 taken 5 times.
7861 if (m_doNConst && nodep->lhsp()->isZero()) {
5939
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
5 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstShiftLOvr $lhsp.isZero, $rhsp , replaceZeroChkPure(nodep,$rhsp) )\n");
5940 5 replaceZeroChkPure(nodep,nodep->rhsp());
5941 5 return true;
5942 }
5943 return false;
5944 }
5945 // Generated by astgen
5946 7856 bool match_ShiftLOvr_1(AstShiftLOvr* nodep) {
5947 // TREEOP ("AstShiftLOvr {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)")
5948
3/4
✓ Branch 0 taken 7856 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 7854 times.
✓ Branch 4 taken 2 times.
7856 if (m_doNConst && nodep->rhsp()->isZero()) {
5949
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
2 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstShiftLOvr $lhsp, $rhsp.isZero , replaceWLhs(nodep) )\n");
5950 replaceWLhs(nodep);
5951 2 return true;
5952 }
5953 return false;
5954 }
5955 // Generated by astgen
5956 7854 bool match_ShiftLOvr_2(AstShiftLOvr* nodep) {
5957 // TREEOP ("AstShiftLOvr{operandHugeShiftL(nodep)}", "replaceZero(nodep)")
5958
2/4
✓ Branch 0 taken 7854 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 7854 times.
✗ Branch 4 not taken.
7854 if (m_doNConst && operandHugeShiftL(nodep)) {
5959 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstShiftLOvr operandHugeShiftL(nodep) , replaceZero(nodep) )\n");
5960 replaceZero(nodep);
5961 return true;
5962 }
5963 return false;
5964 }
5965 // Generated by astgen
5966 351586 bool match_ShiftR_0(AstShiftR* nodep) {
5967 // TREEOP ("AstShiftR {$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)")
5968
4/4
✓ Branch 0 taken 344583 times.
✓ Branch 1 taken 7003 times.
✓ Branch 3 taken 344342 times.
✓ Branch 4 taken 241 times.
351586 if (m_doNConst && nodep->lhsp()->isZero()) {
5969
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 241 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
241 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstShiftR $lhsp.isZero, $rhsp , replaceZeroChkPure(nodep,$rhsp) )\n");
5970 241 replaceZeroChkPure(nodep,nodep->rhsp());
5971 241 return true;
5972 }
5973 return false;
5974 }
5975 // Generated by astgen
5976 351345 bool match_ShiftR_1(AstShiftR* nodep) {
5977 // TREEOP ("AstShiftR {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)")
5978
4/4
✓ Branch 0 taken 344342 times.
✓ Branch 1 taken 7003 times.
✓ Branch 3 taken 308941 times.
✓ Branch 4 taken 35401 times.
351345 if (m_doNConst && nodep->rhsp()->isZero()) {
5979
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 35401 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
35401 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstShiftR $lhsp, $rhsp.isZero , replaceWLhs(nodep) )\n");
5980 replaceWLhs(nodep);
5981 35401 return true;
5982 }
5983 return false;
5984 }
5985 // Generated by astgen
5986 315944 bool match_ShiftR_2(AstShiftR* nodep) {
5987 // TREEOP ("AstShiftR {operandHugeShiftR(nodep)}", "replaceZero(nodep)")
5988
4/4
✓ Branch 0 taken 308941 times.
✓ Branch 1 taken 7003 times.
✓ Branch 3 taken 307838 times.
✓ Branch 4 taken 1103 times.
315944 if (m_doNConst && operandHugeShiftR(nodep)) {
5989
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 1103 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
1103 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstShiftR operandHugeShiftR(nodep) , replaceZero(nodep) )\n");
5990 replaceZero(nodep);
5991 1103 return true;
5992 }
5993 return false;
5994 }
5995 // Generated by astgen
5996 314841 bool match_ShiftR_3(AstShiftR* nodep) {
5997 // TREEOP ("AstShiftR{operandShiftOp(nodep)}", "replaceShiftOp(nodep)")
5998
4/4
✓ Branch 0 taken 307838 times.
✓ Branch 1 taken 7003 times.
✓ Branch 2 taken 9458 times.
✓ Branch 3 taken 298380 times.
314841 if (m_doNConst && operandShiftOp(nodep)) {
5999
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 9458 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
9458 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstShiftR operandShiftOp(nodep) , replaceShiftOp(nodep) )\n");
6000 9458 replaceShiftOp(nodep);
6001 9458 return true;
6002 }
6003 return false;
6004 }
6005 // Generated by astgen
6006 305383 bool match_ShiftR_4(AstShiftR* nodep) {
6007 // TREEOP ("AstShiftR{operandShiftShift(nodep)}", "replaceShiftShift(nodep)")
6008
4/4
✓ Branch 0 taken 298380 times.
✓ Branch 1 taken 7003 times.
✓ Branch 3 taken 291410 times.
✓ Branch 4 taken 6970 times.
305383 if (m_doNConst && operandShiftShift(nodep)) {
6009
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 6970 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
6970 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstShiftR operandShiftShift(nodep) , replaceShiftShift(nodep) )\n");
6010 6970 replaceShiftShift(nodep);
6011 6970 return true;
6012 }
6013 return false;
6014 }
6015 // Generated by astgen
6016 4668 bool match_ShiftROvr_0(AstShiftROvr* nodep) {
6017 // TREEOP ("AstShiftROvr {$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)")
6018
3/4
✓ Branch 0 taken 4668 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 4666 times.
✓ Branch 4 taken 2 times.
4668 if (m_doNConst && nodep->lhsp()->isZero()) {
6019
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
2 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstShiftROvr $lhsp.isZero, $rhsp , replaceZeroChkPure(nodep,$rhsp) )\n");
6020 2 replaceZeroChkPure(nodep,nodep->rhsp());
6021 2 return true;
6022 }
6023 return false;
6024 }
6025 // Generated by astgen
6026 4666 bool match_ShiftROvr_1(AstShiftROvr* nodep) {
6027 // TREEOP ("AstShiftROvr {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)")
6028
3/4
✓ Branch 0 taken 4666 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 4663 times.
✓ Branch 4 taken 3 times.
4666 if (m_doNConst && nodep->rhsp()->isZero()) {
6029
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
3 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstShiftROvr $lhsp, $rhsp.isZero , replaceWLhs(nodep) )\n");
6030 replaceWLhs(nodep);
6031 3 return true;
6032 }
6033 return false;
6034 }
6035 // Generated by astgen
6036 4663 bool match_ShiftROvr_2(AstShiftROvr* nodep) {
6037 // TREEOP ("AstShiftROvr{operandHugeShiftR(nodep)}", "replaceZero(nodep)")
6038
2/4
✓ Branch 0 taken 4663 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 4663 times.
✗ Branch 4 not taken.
4663 if (m_doNConst && operandHugeShiftR(nodep)) {
6039 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstShiftROvr operandHugeShiftR(nodep) , replaceZero(nodep) )\n");
6040 replaceZero(nodep);
6041 return true;
6042 }
6043 return false;
6044 }
6045 // Generated by astgen
6046 9076 bool match_ShiftRS_0(AstShiftRS* nodep) {
6047 // TREEOP ("AstShiftRS {$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)")
6048
4/4
✓ Branch 0 taken 8301 times.
✓ Branch 1 taken 775 times.
✓ Branch 3 taken 8276 times.
✓ Branch 4 taken 25 times.
9076 if (m_doNConst && nodep->lhsp()->isZero()) {
6049
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 25 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
25 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstShiftRS $lhsp.isZero, $rhsp , replaceZeroChkPure(nodep,$rhsp) )\n");
6050 25 replaceZeroChkPure(nodep,nodep->rhsp());
6051 25 return true;
6052 }
6053 return false;
6054 }
6055 // Generated by astgen
6056 9051 bool match_ShiftRS_1(AstShiftRS* nodep) {
6057 // TREEOP ("AstShiftRS {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)")
6058
4/4
✓ Branch 0 taken 8276 times.
✓ Branch 1 taken 775 times.
✓ Branch 3 taken 8256 times.
✓ Branch 4 taken 20 times.
9051 if (m_doNConst && nodep->rhsp()->isZero()) {
6059
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 20 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
20 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstShiftRS $lhsp, $rhsp.isZero , replaceWLhs(nodep) )\n");
6060 replaceWLhs(nodep);
6061 20 return true;
6062 }
6063 return false;
6064 }
6065 // Generated by astgen
6066 659 bool match_ShiftRSOvr_0(AstShiftRSOvr* nodep) {
6067 // TREEOP ("AstShiftRSOvr{$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)")
6068
2/4
✓ Branch 0 taken 659 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 659 times.
✗ Branch 4 not taken.
659 if (m_doNConst && nodep->lhsp()->isZero()) {
6069 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstShiftRSOvr $lhsp.isZero, $rhsp , replaceZeroChkPure(nodep,$rhsp) )\n");
6070 replaceZeroChkPure(nodep,nodep->rhsp());
6071 return true;
6072 }
6073 return false;
6074 }
6075 // Generated by astgen
6076 659 bool match_ShiftRSOvr_1(AstShiftRSOvr* nodep) {
6077 // TREEOP ("AstShiftRSOvr{$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)")
6078
2/4
✓ Branch 0 taken 659 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 659 times.
✗ Branch 4 not taken.
659 if (m_doNConst && nodep->rhsp()->isZero()) {
6079 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstShiftRSOvr $lhsp, $rhsp.isZero , replaceWLhs(nodep) )\n");
6080 replaceWLhs(nodep);
6081 return true;
6082 }
6083 return false;
6084 }
6085 // Generated by astgen
6086 45978 bool match_Sub_0(AstSub* nodep) {
6087 // TREEOP ("AstSub {$lhsp.isZero, $rhsp}", "AstNegate{$rhsp}")
6088
4/4
✓ Branch 0 taken 42104 times.
✓ Branch 1 taken 3874 times.
✓ Branch 3 taken 41984 times.
✓ Branch 4 taken 120 times.
45978 if (m_doNConst && nodep->lhsp()->isZero()) {
6089
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 120 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
120 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstSub $lhsp.isZero, $rhsp , AstNegate $rhsp )\n");
6090 AstNodeExpr* arg1p = nodep->rhsp()->unlinkFrBack();
6091
1/2
✓ Branch 2 taken 120 times.
✗ Branch 3 not taken.
120 AstNodeExpr* newp = new AstNegate(nodep->fileline(), arg1p);
6092 120 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
6093 120 return true;
6094 }
6095 return false;
6096 }
6097 // Generated by astgen
6098 45858 bool match_Sub_1(AstSub* nodep) {
6099 // TREEOP ("AstSub {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)")
6100
4/4
✓ Branch 0 taken 41984 times.
✓ Branch 1 taken 3874 times.
✓ Branch 3 taken 41883 times.
✓ Branch 4 taken 101 times.
45858 if (m_doNConst && nodep->rhsp()->isZero()) {
6101
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 101 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
101 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstSub $lhsp, $rhsp.isZero , replaceWLhs(nodep) )\n");
6102 replaceWLhs(nodep);
6103 101 return true;
6104 }
6105 return false;
6106 }
6107 // Generated by astgen
6108 45757 bool match_Sub_2(AstSub* nodep) {
6109 // TREEOP ("AstSub {$lhsp.castAdd, operandSubAdd(nodep)}", "AstAdd{AstSub{$lhsp->castAdd()->lhsp(),$rhsp}, $lhsp->castAdd()->rhsp()}")
6110
4/4
✓ Branch 0 taken 41883 times.
✓ Branch 1 taken 3874 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 229 times.
45987 if (m_doNConst && VN_IS(nodep->lhsp(),Add) && operandSubAdd(nodep)) {
6111
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
1 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstSub $lhsp.castAdd, operandSubAdd(nodep) , AstAdd AstSub $lhsp->castAdd()->lhsp(),$rhsp , $lhsp->castAdd()->rhsp() )\n");
6112 AstNodeExpr* arg1p = VN_CAST(nodep->lhsp(),Add)->lhsp()->unlinkFrBack();
6113 AstNodeExpr* arg2p = nodep->rhsp()->unlinkFrBack();
6114 AstNodeExpr* arg3p = VN_CAST(nodep->lhsp(),Add)->rhsp()->unlinkFrBack();
6115
3/6
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
1 AstNodeExpr* newp = new AstAdd(nodep->fileline(), new AstSub(nodep->fileline(), arg1p, arg2p), arg3p);
6116 1 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
6117 1 return true;
6118 }
6119 return false;
6120 }
6121 // Generated by astgen
6122 45756 bool match_Sub_3(AstSub* nodep) {
6123 // TREEOP ("AstSub {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)")
6124
4/4
✓ Branch 0 taken 41882 times.
✓ Branch 1 taken 3874 times.
✓ Branch 3 taken 41830 times.
✓ Branch 4 taken 52 times.
45756 if (m_doNConst && operandsSame(nodep->lhsp(),nodep->rhsp())) {
6125
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 52 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
52 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstSub operandsSame($lhsp,,$rhsp) , replaceZero(nodep) )\n");
6126 replaceZero(nodep);
6127 52 return true;
6128 }
6129 return false;
6130 }
6131 // Generated by astgen
6132 bool match_SubstrN_0(AstSubstrN* nodep) {
6133 // TREEOPA("AstSubstrN{$lhsp.castConst, $rhsp.castConst, $thsp.castConst}", "replaceConst(nodep)")
6134 if (VN_IS(nodep->lhsp(),Const) && VN_IS(nodep->rhsp(),Const) && VN_IS(nodep->thsp(),Const)) {
6135 UINFO(7, cvtToHex(nodep) << " TREEOPA( AstSubstrN $lhsp.castConst, $rhsp.castConst, $thsp.castConst , replaceConst(nodep) )\n");
6136 replaceConst(nodep);
6137 return true;
6138 }
6139 return false;
6140 }
6141 // Generated by astgen
6142 279759 bool match_WordSel_0(AstWordSel* nodep) {
6143 // TREEOP ("AstWordSel{operandWordOOB(nodep)}", "replaceZero(nodep)")
6144
2/4
✓ Branch 0 taken 279759 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 279759 times.
✗ Branch 4 not taken.
279759 if (m_doNConst && operandWordOOB(nodep)) {
6145 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstWordSel operandWordOOB(nodep) , replaceZero(nodep) )\n");
6146 replaceZero(nodep);
6147 return true;
6148 }
6149 return false;
6150 }
6151 // Generated by astgen
6152 142818 bool match_Xor_0(AstXor* nodep) {
6153 // TREEOP ("AstXor {$lhsp.isZero, $rhsp}", "replaceWRhs(nodep)")
6154
4/4
✓ Branch 0 taken 131120 times.
✓ Branch 1 taken 11698 times.
✓ Branch 3 taken 130145 times.
✓ Branch 4 taken 975 times.
142818 if (m_doNConst && nodep->lhsp()->isZero()) {
6155
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 975 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
975 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstXor $lhsp.isZero, $rhsp , replaceWRhs(nodep) )\n");
6156 replaceWRhs(nodep);
6157 975 return true;
6158 }
6159 return false;
6160 }
6161 // Generated by astgen
6162 141843 bool match_Xor_1(AstXor* nodep) {
6163 // TREEOP ("AstXor {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)")
6164
3/4
✓ Branch 0 taken 130145 times.
✓ Branch 1 taken 11698 times.
✓ Branch 3 taken 130145 times.
✗ Branch 4 not taken.
141843 if (m_doNConst && nodep->rhsp()->isZero()) {
6165 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstXor $lhsp, $rhsp.isZero , replaceWLhs(nodep) )\n");
6166 replaceWLhs(nodep);
6167 return true;
6168 }
6169 return false;
6170 }
6171 // Generated by astgen
6172 141843 bool match_Xor_2(AstXor* nodep) {
6173 // TREEOP ("AstXor {$lhsp.isAllOnes, $rhsp}", "AstNot{$rhsp}")
6174
4/4
✓ Branch 0 taken 130145 times.
✓ Branch 1 taken 11698 times.
✓ Branch 3 taken 129965 times.
✓ Branch 4 taken 180 times.
141843 if (m_doNConst && nodep->lhsp()->isAllOnes()) {
6175
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 180 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
180 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstXor $lhsp.isAllOnes, $rhsp , AstNot $rhsp )\n");
6176 AstNodeExpr* arg1p = nodep->rhsp()->unlinkFrBack();
6177
1/2
✓ Branch 2 taken 180 times.
✗ Branch 3 not taken.
180 AstNodeExpr* newp = new AstNot(nodep->fileline(), arg1p);
6178 180 nodep->replaceWith(newp);VL_DO_DANGLING(nodep->deleteTree(), nodep);
6179 180 return true;
6180 }
6181 return false;
6182 }
6183 // Generated by astgen
6184 141663 bool match_Xor_3(AstXor* nodep) {
6185 // TREEOP ("AstXor {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)")
6186
4/4
✓ Branch 0 taken 129965 times.
✓ Branch 1 taken 11698 times.
✓ Branch 3 taken 129801 times.
✓ Branch 4 taken 164 times.
141663 if (m_doNConst && operandsSame(nodep->lhsp(),nodep->rhsp())) {
6187
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 164 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
164 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstXor operandsSame($lhsp,,$rhsp) , replaceZero(nodep) )\n");
6188 replaceZero(nodep);
6189 164 return true;
6190 }
6191 return false;
6192 }
6193 // Generated by astgen
6194 141499 bool match_Xor_4(AstXor* nodep) {
6195 // TREEOP ("AstXor {operandShiftSame(nodep)}", "replaceShiftSame(nodep)")
6196
4/4
✓ Branch 0 taken 129801 times.
✓ Branch 1 taken 11698 times.
✓ Branch 3 taken 129654 times.
✓ Branch 4 taken 147 times.
141499 if (m_doNConst && operandShiftSame(nodep)) {
6197
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 147 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
147 UINFO(7, cvtToHex(nodep) << " TREEOP ( AstXor operandShiftSame(nodep) , replaceShiftSame(nodep) )\n");
6198 147 replaceShiftSame(nodep);
6199 147 return true;
6200 }
6201 return false;
6202 }
6203 // Generated by astgen
6204 141352 bool match_Xor_5(AstXor* nodep) {
6205 // TREEOPC("AstXor {matchBitOpTree(nodep)}", "DONE")
6206
4/4
✓ Branch 0 taken 12488 times.
✓ Branch 1 taken 128864 times.
✓ Branch 3 taken 12484 times.
✓ Branch 4 taken 4 times.
141352 if (m_doCpp && matchBitOpTree(nodep)) {
6207
1/10
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
4 UINFO(7, cvtToHex(nodep) << " TREEOPC( AstXor matchBitOpTree(nodep) , DONE )\n");
6208
6209 4 return true;
6210 }
6211 return false;
6212 }
6213 // TREEOP visitors, call each base type's match
6214 // Bottom class up, as more simple transforms are generally better
6215 // Generated by astgen
6216 void visit(AstAcosD* nodep) override {
6217 iterateChildren(nodep);
6218 if (match_NodeUniop_0(nodep)) return;
6219 }
6220 // Generated by astgen
6221 void visit(AstAcoshD* nodep) override {
6222 iterateChildren(nodep);
6223 if (match_NodeUniop_0(nodep)) return;
6224 }
6225 // Generated by astgen
6226 60062 void visit(AstAdd* nodep) override {
6227 60062 iterateChildren(nodep);
6228
2/2
✓ Branch 1 taken 59664 times.
✓ Branch 2 taken 398 times.
60062 if (match_NodeBiop_0(nodep)) return;
6229
2/2
✓ Branch 1 taken 57276 times.
✓ Branch 2 taken 2388 times.
59664 if (match_NodeBiCom_0(nodep)) return;
6230
2/2
✓ Branch 1 taken 57275 times.
✓ Branch 2 taken 1 times.
57276 if (match_NodeBiComAsv_0(nodep)) return;
6231
1/2
✓ Branch 1 taken 57275 times.
✗ Branch 2 not taken.
57275 if (match_NodeBiComAsv_1(nodep)) return;
6232
2/2
✓ Branch 1 taken 57262 times.
✓ Branch 2 taken 13 times.
57275 if (match_NodeBiComAsv_2(nodep)) return;
6233
2/2
✓ Branch 1 taken 57257 times.
✓ Branch 2 taken 5 times.
57262 if (match_NodeBiComAsv_3(nodep)) return;
6234
2/2
✓ Branch 1 taken 57018 times.
✓ Branch 2 taken 239 times.
57257 if (match_Add_0(nodep)) return;
6235 57018 if (match_Add_1(nodep)) return;
6236 }
6237 // Generated by astgen
6238 void visit(AstAddD* nodep) override {
6239 iterateChildren(nodep);
6240 if (match_NodeBiop_0(nodep)) return;
6241 if (match_NodeBiCom_0(nodep)) return;
6242 if (match_NodeBiComAsv_0(nodep)) return;
6243 if (match_NodeBiComAsv_1(nodep)) return;
6244 if (match_NodeBiComAsv_2(nodep)) return;
6245 if (match_NodeBiComAsv_3(nodep)) return;
6246 }
6247 // Generated by astgen
6248 640096 void visit(AstAnd* nodep) override {
6249 640096 iterateChildren(nodep);
6250
2/2
✓ Branch 1 taken 564903 times.
✓ Branch 2 taken 75193 times.
640096 if (match_NodeBiop_0(nodep)) return;
6251
2/2
✓ Branch 1 taken 553454 times.
✓ Branch 2 taken 11449 times.
564903 if (match_NodeBiCom_0(nodep)) return;
6252
2/2
✓ Branch 1 taken 542828 times.
✓ Branch 2 taken 10626 times.
553454 if (match_NodeBiComAsv_0(nodep)) return;
6253
1/2
✓ Branch 1 taken 542828 times.
✗ Branch 2 not taken.
542828 if (match_NodeBiComAsv_1(nodep)) return;
6254
2/2
✓ Branch 1 taken 542492 times.
✓ Branch 2 taken 336 times.
542828 if (match_NodeBiComAsv_2(nodep)) return;
6255
2/2
✓ Branch 1 taken 542177 times.
✓ Branch 2 taken 315 times.
542492 if (match_NodeBiComAsv_3(nodep)) return;
6256
2/2
✓ Branch 1 taken 534320 times.
✓ Branch 2 taken 7857 times.
542177 if (match_And_0(nodep)) return;
6257
1/2
✓ Branch 1 taken 534320 times.
✗ Branch 2 not taken.
534320 if (match_And_1(nodep)) return;
6258
2/2
✓ Branch 1 taken 534187 times.
✓ Branch 2 taken 133 times.
534320 if (match_And_2(nodep)) return;
6259
1/2
✓ Branch 1 taken 534187 times.
✗ Branch 2 not taken.
534187 if (match_And_3(nodep)) return;
6260
2/2
✓ Branch 1 taken 534168 times.
✓ Branch 2 taken 19 times.
534187 if (match_And_4(nodep)) return;
6261
2/2
✓ Branch 1 taken 534097 times.
✓ Branch 2 taken 71 times.
534168 if (match_And_5(nodep)) return;
6262
1/2
✓ Branch 1 taken 534097 times.
✗ Branch 2 not taken.
534097 if (match_And_6(nodep)) return;
6263
2/2
✓ Branch 1 taken 532748 times.
✓ Branch 2 taken 1349 times.
534097 if (match_And_7(nodep)) return;
6264
1/2
✓ Branch 1 taken 532748 times.
✗ Branch 2 not taken.
532748 if (match_And_8(nodep)) return;
6265
2/2
✓ Branch 1 taken 508560 times.
✓ Branch 2 taken 24188 times.
532748 if (match_And_9(nodep)) return;
6266
1/2
✓ Branch 1 taken 508560 times.
✗ Branch 2 not taken.
508560 if (match_And_10(nodep)) return;
6267
2/2
✓ Branch 1 taken 508260 times.
✓ Branch 2 taken 300 times.
508560 if (match_And_11(nodep)) return;
6268 508260 if (match_And_12(nodep)) return;
6269 }
6270 // Generated by astgen
6271 virtual void visitGen(AstArraySel* nodep) {
6272 if (match_NodeBiop_0(nodep)) return;
6273 }
6274 // Generated by astgen
6275 void visit(AstAsinD* nodep) override {
6276 iterateChildren(nodep);
6277 if (match_NodeUniop_0(nodep)) return;
6278 }
6279 // Generated by astgen
6280 void visit(AstAsinhD* nodep) override {
6281 iterateChildren(nodep);
6282 if (match_NodeUniop_0(nodep)) return;
6283 }
6284 // Generated by astgen
6285 void visit(AstAssocSel* nodep) override {
6286 iterateChildren(nodep);
6287 if (match_NodeBiop_0(nodep)) return;
6288 }
6289 // Generated by astgen
6290 void visit(AstAtan2D* nodep) override {
6291 iterateChildren(nodep);
6292 if (match_NodeBiop_0(nodep)) return;
6293 }
6294 // Generated by astgen
6295 void visit(AstAtanD* nodep) override {
6296 iterateChildren(nodep);
6297 if (match_NodeUniop_0(nodep)) return;
6298 }
6299 // Generated by astgen
6300 void visit(AstAtanhD* nodep) override {
6301 iterateChildren(nodep);
6302 if (match_NodeUniop_0(nodep)) return;
6303 }
6304 // Generated by astgen
6305 void visit(AstAtoN* nodep) override {
6306 iterateChildren(nodep);
6307 if (match_NodeUniop_0(nodep)) return;
6308 }
6309 // Generated by astgen
6310 void visit(AstBitsToRealD* nodep) override {
6311 iterateChildren(nodep);
6312 if (match_NodeUniop_0(nodep)) return;
6313 }
6314 // Generated by astgen
6315 void visit(AstBufIf1* nodep) override {
6316 iterateChildren(nodep);
6317 if (match_NodeBiop_0(nodep)) return;
6318 }
6319 // Generated by astgen
6320 virtual void visitGen(AstCAwait* nodep) {
6321 if (match_NodeUniop_0(nodep)) return;
6322 }
6323 // Generated by astgen
6324 359053 void visit(AstCCast* nodep) override {
6325 359053 iterateChildren(nodep);
6326 359053 if (match_NodeUniop_0(nodep)) return;
6327 }
6328 // Generated by astgen
6329 void visit(AstCLog2* nodep) override {
6330 iterateChildren(nodep);
6331 if (match_NodeUniop_0(nodep)) return;
6332 }
6333 // Generated by astgen
6334 void visit(AstCastDynamic* nodep) override {
6335 iterateChildren(nodep);
6336 if (match_NodeBiop_0(nodep)) return;
6337 }
6338 // Generated by astgen
6339 void visit(AstCastWrap* nodep) override {
6340 iterateChildren(nodep);
6341 if (match_NodeUniop_0(nodep)) return;
6342 }
6343 // Generated by astgen
6344 void visit(AstCeilD* nodep) override {
6345 iterateChildren(nodep);
6346 if (match_NodeUniop_0(nodep)) return;
6347 }
6348 // Generated by astgen
6349 void visit(AstCompareNN* nodep) override {
6350 iterateChildren(nodep);
6351 if (match_NodeBiop_0(nodep)) return;
6352 }
6353 // Generated by astgen
6354 1320868 void visit(AstConcat* nodep) override {
6355 1320868 iterateChildren(nodep);
6356
2/2
✓ Branch 1 taken 1318044 times.
✓ Branch 2 taken 2824 times.
1320868 if (match_NodeBiop_0(nodep)) return;
6357
1/2
✓ Branch 1 taken 1318044 times.
✗ Branch 2 not taken.
1318044 if (match_Concat_0(nodep)) return;
6358
2/2
✓ Branch 1 taken 1255195 times.
✓ Branch 2 taken 62849 times.
1318044 if (match_Concat_1(nodep)) return;
6359
2/2
✓ Branch 1 taken 1220903 times.
✓ Branch 2 taken 34292 times.
1255195 if (match_Concat_2(nodep)) return;
6360
2/2
✓ Branch 1 taken 1220901 times.
✓ Branch 2 taken 2 times.
1220903 if (match_Concat_3(nodep)) return;
6361
1/2
✓ Branch 1 taken 1220901 times.
✗ Branch 2 not taken.
1220901 if (match_Concat_4(nodep)) return;
6362 1220901 if (match_Concat_5(nodep)) return;
6363 }
6364 // Generated by astgen
6365 void visit(AstConcatN* nodep) override {
6366 iterateChildren(nodep);
6367 if (match_NodeBiop_0(nodep)) return;
6368 }
6369 // Generated by astgen with short-circuiting
6370 852585 void visit(AstCond* nodep) override {
6371
1/2
✓ Branch 0 taken 852585 times.
✗ Branch 1 not taken.
852585 iterateAndNextNull(nodep->condp());
6372
2/2
✓ Branch 1 taken 848709 times.
✓ Branch 2 taken 3876 times.
852585 if (match_Cond_0(nodep)) return;
6373
2/2
✓ Branch 1 taken 833911 times.
✓ Branch 2 taken 14798 times.
848709 if (match_Cond_1(nodep)) return;
6374 iterateAndNextNull(nodep->thenp());
6375 iterateAndNextNull(nodep->elsep());
6376
1/2
✓ Branch 1 taken 833911 times.
✗ Branch 2 not taken.
833911 if (match_NodeCond_0(nodep)) return;
6377
1/2
✓ Branch 1 taken 833911 times.
✗ Branch 2 not taken.
833911 if (match_NodeCond_1(nodep)) return;
6378
2/2
✓ Branch 1 taken 833909 times.
✓ Branch 2 taken 2 times.
833911 if (match_NodeCond_2(nodep)) return;
6379
2/2
✓ Branch 1 taken 833782 times.
✓ Branch 2 taken 127 times.
833909 if (match_NodeCond_3(nodep)) return;
6380
2/2
✓ Branch 1 taken 832744 times.
✓ Branch 2 taken 1038 times.
833782 if (match_NodeCond_4(nodep)) return;
6381
2/2
✓ Branch 1 taken 832651 times.
✓ Branch 2 taken 93 times.
832744 if (match_NodeCond_5(nodep)) return;
6382
2/2
✓ Branch 1 taken 832547 times.
✓ Branch 2 taken 104 times.
832651 if (match_NodeCond_6(nodep)) return;
6383
2/2
✓ Branch 1 taken 832440 times.
✓ Branch 2 taken 107 times.
832547 if (match_NodeCond_7(nodep)) return;
6384
2/2
✓ Branch 1 taken 832326 times.
✓ Branch 2 taken 114 times.
832440 if (match_NodeCond_8(nodep)) return;
6385
2/2
✓ Branch 1 taken 831411 times.
✓ Branch 2 taken 915 times.
832326 if (match_NodeCond_9(nodep)) return;
6386 831411 if (match_Cond_2(nodep)) return;
6387 }
6388 // Generated by astgen
6389 void visit(AstCondBound* nodep) override {
6390 iterateChildren(nodep);
6391 if (match_NodeCond_0(nodep)) return;
6392 if (match_NodeCond_1(nodep)) return;
6393 if (match_NodeCond_2(nodep)) return;
6394 if (match_NodeCond_3(nodep)) return;
6395 if (match_NodeCond_4(nodep)) return;
6396 if (match_NodeCond_5(nodep)) return;
6397 if (match_NodeCond_6(nodep)) return;
6398 if (match_NodeCond_7(nodep)) return;
6399 if (match_NodeCond_8(nodep)) return;
6400 if (match_NodeCond_9(nodep)) return;
6401 }
6402 // Generated by astgen
6403 void visit(AstCosD* nodep) override {
6404 iterateChildren(nodep);
6405 if (match_NodeUniop_0(nodep)) return;
6406 }
6407 // Generated by astgen
6408 void visit(AstCoshD* nodep) override {
6409 iterateChildren(nodep);
6410 if (match_NodeUniop_0(nodep)) return;
6411 }
6412 // Generated by astgen
6413 void visit(AstCountBits* nodep) override {
6414 iterateChildren(nodep);
6415 if (match_NodeQuadop_0(nodep)) return;
6416 }
6417 // Generated by astgen
6418 void visit(AstCountOnes* nodep) override {
6419 iterateChildren(nodep);
6420 if (match_NodeUniop_0(nodep)) return;
6421 }
6422 // Generated by astgen
6423 void visit(AstCvtPackString* nodep) override {
6424 iterateChildren(nodep);
6425 if (match_NodeUniop_0(nodep)) return;
6426 if (match_CvtPackString_0(nodep)) return;
6427 }
6428 // Generated by astgen
6429 void visit(AstDistChiSquare* nodep) override {
6430 iterateChildren(nodep);
6431 if (match_NodeBiop_0(nodep)) return;
6432 }
6433 // Generated by astgen
6434 void visit(AstDistExponential* nodep) override {
6435 iterateChildren(nodep);
6436 if (match_NodeBiop_0(nodep)) return;
6437 }
6438 // Generated by astgen
6439 void visit(AstDistPoisson* nodep) override {
6440 iterateChildren(nodep);
6441 if (match_NodeBiop_0(nodep)) return;
6442 }
6443 // Generated by astgen
6444 void visit(AstDistT* nodep) override {
6445 iterateChildren(nodep);
6446 if (match_NodeBiop_0(nodep)) return;
6447 }
6448 // Generated by astgen
6449 void visit(AstDiv* nodep) override {
6450 iterateChildren(nodep);
6451 if (match_NodeBiop_0(nodep)) return;
6452 if (match_Div_0(nodep)) return;
6453 if (match_Div_1(nodep)) return;
6454 if (match_Div_2(nodep)) return;
6455 if (match_Div_3(nodep)) return;
6456 }
6457 // Generated by astgen
6458 void visit(AstDivD* nodep) override {
6459 iterateChildren(nodep);
6460 if (match_NodeBiop_0(nodep)) return;
6461 }
6462 // Generated by astgen
6463 void visit(AstDivS* nodep) override {
6464 iterateChildren(nodep);
6465 if (match_NodeBiop_0(nodep)) return;
6466 if (match_DivS_0(nodep)) return;
6467 if (match_DivS_1(nodep)) return;
6468 if (match_DivS_2(nodep)) return;
6469 }
6470 // Generated by astgen
6471 61038 void visit(AstEq* nodep) override {
6472 61038 iterateChildren(nodep);
6473
2/2
✓ Branch 1 taken 60575 times.
✓ Branch 2 taken 463 times.
61038 if (match_NodeBiop_0(nodep)) return;
6474
2/2
✓ Branch 1 taken 60139 times.
✓ Branch 2 taken 436 times.
60575 if (match_NodeBiCom_0(nodep)) return;
6475
2/2
✓ Branch 1 taken 60056 times.
✓ Branch 2 taken 83 times.
60139 if (match_Eq_0(nodep)) return;
6476
2/2
✓ Branch 1 taken 59832 times.
✓ Branch 2 taken 224 times.
60056 if (match_Eq_1(nodep)) return;
6477
2/2
✓ Branch 1 taken 59761 times.
✓ Branch 2 taken 71 times.
59832 if (match_Eq_2(nodep)) return;
6478
2/2
✓ Branch 1 taken 59713 times.
✓ Branch 2 taken 48 times.
59761 if (match_Eq_3(nodep)) return;
6479
1/2
✓ Branch 1 taken 59713 times.
✗ Branch 2 not taken.
59713 if (match_Eq_4(nodep)) return;
6480
2/2
✓ Branch 1 taken 59683 times.
✓ Branch 2 taken 30 times.
59713 if (match_Eq_5(nodep)) return;
6481 59683 if (match_Eq_6(nodep)) return;
6482 }
6483 // Generated by astgen
6484 void visit(AstEqCase* nodep) override {
6485 iterateChildren(nodep);
6486 if (match_NodeBiop_0(nodep)) return;
6487 if (match_NodeBiCom_0(nodep)) return;
6488 if (match_EqCase_0(nodep)) return;
6489 }
6490 // Generated by astgen
6491 void visit(AstEqD* nodep) override {
6492 iterateChildren(nodep);
6493 if (match_NodeBiop_0(nodep)) return;
6494 if (match_NodeBiCom_0(nodep)) return;
6495 if (match_EqD_0(nodep)) return;
6496 }
6497 // Generated by astgen
6498 void visit(AstEqN* nodep) override {
6499 iterateChildren(nodep);
6500 if (match_NodeBiop_0(nodep)) return;
6501 if (match_NodeBiCom_0(nodep)) return;
6502 if (match_EqN_0(nodep)) return;
6503 }
6504 // Generated by astgen
6505 void visit(AstEqT* nodep) override {
6506 iterateChildren(nodep);
6507 if (match_NodeBiop_0(nodep)) return;
6508 if (match_NodeBiCom_0(nodep)) return;
6509 }
6510 // Generated by astgen
6511 void visit(AstEqWild* nodep) override {
6512 iterateChildren(nodep);
6513 if (match_NodeBiop_0(nodep)) return;
6514 if (match_EqWild_0(nodep)) return;
6515 }
6516 // Generated by astgen
6517 void visit(AstExpD* nodep) override {
6518 iterateChildren(nodep);
6519 if (match_NodeUniop_0(nodep)) return;
6520 }
6521 // Generated by astgen
6522 1567183 void visit(AstExtend* nodep) override {
6523 1567183 iterateChildren(nodep);
6524
2/2
✓ Branch 1 taken 1486080 times.
✓ Branch 2 taken 81103 times.
1567183 if (match_NodeUniop_0(nodep)) return;
6525
1/2
✓ Branch 1 taken 1486080 times.
✗ Branch 2 not taken.
1486080 if (match_Extend_0(nodep)) return;
6526 1486080 if (match_Extend_1(nodep)) return;
6527 }
6528 // Generated by astgen
6529 245668 void visit(AstExtendS* nodep) override {
6530 245668 iterateChildren(nodep);
6531
2/2
✓ Branch 1 taken 243920 times.
✓ Branch 2 taken 1748 times.
245668 if (match_NodeUniop_0(nodep)) return;
6532 243920 if (match_ExtendS_0(nodep)) return;
6533 }
6534 // Generated by astgen
6535 void visit(AstFEof* nodep) override {
6536 iterateChildren(nodep);
6537 if (match_NodeUniop_0(nodep)) return;
6538 }
6539 // Generated by astgen
6540 void visit(AstFGetC* nodep) override {
6541 iterateChildren(nodep);
6542 if (match_NodeUniop_0(nodep)) return;
6543 }
6544 // Generated by astgen
6545 void visit(AstFGetS* nodep) override {
6546 iterateChildren(nodep);
6547 if (match_NodeBiop_0(nodep)) return;
6548 }
6549 // Generated by astgen
6550 void visit(AstFUngetC* nodep) override {
6551 iterateChildren(nodep);
6552 if (match_NodeBiop_0(nodep)) return;
6553 }
6554 // Generated by astgen
6555 void visit(AstFloorD* nodep) override {
6556 iterateChildren(nodep);
6557 if (match_NodeUniop_0(nodep)) return;
6558 }
6559 // Generated by astgen
6560 void visit(AstGetcN* nodep) override {
6561 iterateChildren(nodep);
6562 if (match_NodeBiop_0(nodep)) return;
6563 }
6564 // Generated by astgen
6565 void visit(AstGetcRefN* nodep) override {
6566 iterateChildren(nodep);
6567 if (match_NodeBiop_0(nodep)) return;
6568 }
6569 // Generated by astgen
6570 42699 void visit(AstGt* nodep) override {
6571 42699 iterateChildren(nodep);
6572
2/2
✓ Branch 1 taken 42664 times.
✓ Branch 2 taken 35 times.
42699 if (match_Gt_2(nodep)) return;
6573
2/2
✓ Branch 1 taken 42508 times.
✓ Branch 2 taken 156 times.
42664 if (match_Gt_1(nodep)) return;
6574
2/2
✓ Branch 1 taken 42182 times.
✓ Branch 2 taken 326 times.
42508 if (match_NodeBiop_0(nodep)) return;
6575
2/2
✓ Branch 1 taken 39772 times.
✓ Branch 2 taken 2410 times.
42182 if (match_Gt_0(nodep)) return;
6576
2/2
✓ Branch 1 taken 39742 times.
✓ Branch 2 taken 30 times.
39772 if (match_Gt_3(nodep)) return;
6577
2/2
✓ Branch 1 taken 39496 times.
✓ Branch 2 taken 246 times.
39742 if (match_Gt_4(nodep)) return;
6578
2/2
✓ Branch 1 taken 39462 times.
✓ Branch 2 taken 34 times.
39496 if (match_Gt_5(nodep)) return;
6579 39462 if (match_Gt_6(nodep)) return;
6580 }
6581 // Generated by astgen
6582 void visit(AstGtD* nodep) override {
6583 iterateChildren(nodep);
6584 if (match_NodeBiop_0(nodep)) return;
6585 if (match_GtD_0(nodep)) return;
6586 }
6587 // Generated by astgen
6588 void visit(AstGtN* nodep) override {
6589 iterateChildren(nodep);
6590 if (match_NodeBiop_0(nodep)) return;
6591 if (match_GtN_0(nodep)) return;
6592 }
6593 // Generated by astgen
6594 4302 void visit(AstGtS* nodep) override {
6595 4302 iterateChildren(nodep);
6596
2/2
✓ Branch 1 taken 4296 times.
✓ Branch 2 taken 6 times.
4302 if (match_NodeBiop_0(nodep)) return;
6597
2/2
✓ Branch 1 taken 4266 times.
✓ Branch 2 taken 30 times.
4296 if (match_GtS_0(nodep)) return;
6598 4266 if (match_GtS_1(nodep)) return;
6599 }
6600 // Generated by astgen
6601 146655 void visit(AstGte* nodep) override {
6602 146655 iterateChildren(nodep);
6603
2/2
✓ Branch 1 taken 136897 times.
✓ Branch 2 taken 9758 times.
146655 if (match_Gte_2(nodep)) return;
6604
2/2
✓ Branch 1 taken 87388 times.
✓ Branch 2 taken 49509 times.
136897 if (match_Gte_1(nodep)) return;
6605
2/2
✓ Branch 1 taken 43057 times.
✓ Branch 2 taken 44331 times.
87388 if (match_NodeBiop_0(nodep)) return;
6606
2/2
✓ Branch 1 taken 42638 times.
✓ Branch 2 taken 419 times.
43057 if (match_Gte_0(nodep)) return;
6607
2/2
✓ Branch 1 taken 42522 times.
✓ Branch 2 taken 116 times.
42638 if (match_Gte_3(nodep)) return;
6608
2/2
✓ Branch 1 taken 42290 times.
✓ Branch 2 taken 232 times.
42522 if (match_Gte_4(nodep)) return;
6609 42290 if (match_Gte_5(nodep)) return;
6610 }
6611 // Generated by astgen
6612 void visit(AstGteD* nodep) override {
6613 iterateChildren(nodep);
6614 if (match_NodeBiop_0(nodep)) return;
6615 if (match_GteD_0(nodep)) return;
6616 }
6617 // Generated by astgen
6618 void visit(AstGteN* nodep) override {
6619 iterateChildren(nodep);
6620 if (match_NodeBiop_0(nodep)) return;
6621 if (match_GteN_0(nodep)) return;
6622 }
6623 // Generated by astgen
6624 3667 void visit(AstGteS* nodep) override {
6625 3667 iterateChildren(nodep);
6626
2/2
✓ Branch 1 taken 3661 times.
✓ Branch 2 taken 6 times.
3667 if (match_NodeBiop_0(nodep)) return;
6627
2/2
✓ Branch 1 taken 3637 times.
✓ Branch 2 taken 24 times.
3661 if (match_GteS_0(nodep)) return;
6628 3637 if (match_GteS_1(nodep)) return;
6629 }
6630 // Generated by astgen
6631 void visit(AstHypotD* nodep) override {
6632 iterateChildren(nodep);
6633 if (match_NodeBiop_0(nodep)) return;
6634 }
6635 // Generated by astgen
6636 void visit(AstISToRD* nodep) override {
6637 iterateChildren(nodep);
6638 if (match_NodeUniop_0(nodep)) return;
6639 }
6640 // Generated by astgen
6641 void visit(AstIToRD* nodep) override {
6642 iterateChildren(nodep);
6643 if (match_NodeUniop_0(nodep)) return;
6644 }
6645 // Generated by astgen
6646 void visit(AstIsUnbounded* nodep) override {
6647 iterateChildren(nodep);
6648 if (match_NodeUniop_0(nodep)) return;
6649 if (match_IsUnbounded_0(nodep)) return;
6650 }
6651 // Generated by astgen
6652 void visit(AstIsUnknown* nodep) override {
6653 iterateChildren(nodep);
6654 if (match_NodeUniop_0(nodep)) return;
6655 }
6656 // Generated by astgen
6657 void visit(AstLenN* nodep) override {
6658 iterateChildren(nodep);
6659 if (match_NodeUniop_0(nodep)) return;
6660 }
6661 // Generated by astgen
6662 void visit(AstLog10D* nodep) override {
6663 iterateChildren(nodep);
6664 if (match_NodeUniop_0(nodep)) return;
6665 }
6666 // Generated by astgen with short-circuiting
6667 8542 void visit(AstLogAnd* nodep) override {
6668
1/2
✓ Branch 0 taken 8542 times.
✗ Branch 1 not taken.
8542 iterateAndNextNull(nodep->lhsp());
6669
2/2
✓ Branch 1 taken 8425 times.
✓ Branch 2 taken 117 times.
8542 if (match_LogAnd_0(nodep)) return;
6670 iterateAndNextNull(nodep->rhsp());
6671
2/2
✓ Branch 1 taken 8090 times.
✓ Branch 2 taken 335 times.
8425 if (match_NodeBiop_0(nodep)) return;
6672
1/2
✓ Branch 1 taken 8090 times.
✗ Branch 2 not taken.
8090 if (match_LogAnd_1(nodep)) return;
6673
2/2
✓ Branch 1 taken 8044 times.
✓ Branch 2 taken 46 times.
8090 if (match_LogAnd_2(nodep)) return;
6674
2/2
✓ Branch 1 taken 7711 times.
✓ Branch 2 taken 333 times.
8044 if (match_LogAnd_3(nodep)) return;
6675
2/2
✓ Branch 1 taken 7362 times.
✓ Branch 2 taken 349 times.
7711 if (match_LogAnd_4(nodep)) return;
6676
1/2
✓ Branch 1 taken 7362 times.
✗ Branch 2 not taken.
7362 if (match_LogAnd_5(nodep)) return;
6677 7362 if (match_LogAnd_6(nodep)) return;
6678 }
6679 // Generated by astgen
6680 void visit(AstLogD* nodep) override {
6681 iterateChildren(nodep);
6682 if (match_NodeUniop_0(nodep)) return;
6683 }
6684 // Generated by astgen
6685 void visit(AstLogEq* nodep) override {
6686 iterateChildren(nodep);
6687 if (match_NodeBiop_0(nodep)) return;
6688 if (match_NodeBiCom_0(nodep)) return;
6689 if (match_LogEq_0(nodep)) return;
6690 }
6691 // Generated by astgen with short-circuiting
6692 void visit(AstLogIf* nodep) override {
6693 iterateAndNextNull(nodep->lhsp());
6694 if (match_LogIf_0(nodep)) return;
6695 iterateAndNextNull(nodep->rhsp());
6696 if (match_NodeBiop_0(nodep)) return;
6697 if (match_LogIf_1(nodep)) return;
6698 }
6699 // Generated by astgen
6700 73390 void visit(AstLogNot* nodep) override {
6701 73390 iterateChildren(nodep);
6702
2/2
✓ Branch 1 taken 65834 times.
✓ Branch 2 taken 7556 times.
73390 if (match_NodeUniop_0(nodep)) return;
6703
1/2
✓ Branch 1 taken 65834 times.
✗ Branch 2 not taken.
65834 if (match_LogNot_0(nodep)) return;
6704
1/2
✓ Branch 1 taken 65834 times.
✗ Branch 2 not taken.
65834 if (match_LogNot_1(nodep)) return;
6705
1/2
✓ Branch 1 taken 65834 times.
✗ Branch 2 not taken.
65834 if (match_LogNot_2(nodep)) return;
6706
1/2
✓ Branch 1 taken 65834 times.
✗ Branch 2 not taken.
65834 if (match_LogNot_3(nodep)) return;
6707
1/2
✓ Branch 1 taken 65834 times.
✗ Branch 2 not taken.
65834 if (match_LogNot_4(nodep)) return;
6708
2/2
✓ Branch 1 taken 65613 times.
✓ Branch 2 taken 221 times.
65834 if (match_LogNot_5(nodep)) return;
6709
2/2
✓ Branch 1 taken 65398 times.
✓ Branch 2 taken 215 times.
65613 if (match_LogNot_6(nodep)) return;
6710
2/2
✓ Branch 1 taken 65206 times.
✓ Branch 2 taken 192 times.
65398 if (match_LogNot_7(nodep)) return;
6711
2/2
✓ Branch 1 taken 65177 times.
✓ Branch 2 taken 29 times.
65206 if (match_LogNot_8(nodep)) return;
6712
2/2
✓ Branch 1 taken 64985 times.
✓ Branch 2 taken 192 times.
65177 if (match_LogNot_9(nodep)) return;
6713
2/2
✓ Branch 1 taken 64962 times.
✓ Branch 2 taken 23 times.
64985 if (match_LogNot_10(nodep)) return;
6714
2/2
✓ Branch 1 taken 64764 times.
✓ Branch 2 taken 198 times.
64962 if (match_LogNot_11(nodep)) return;
6715
2/2
✓ Branch 1 taken 64747 times.
✓ Branch 2 taken 17 times.
64764 if (match_LogNot_12(nodep)) return;
6716
2/2
✓ Branch 1 taken 64563 times.
✓ Branch 2 taken 184 times.
64747 if (match_LogNot_13(nodep)) return;
6717
2/2
✓ Branch 1 taken 64540 times.
✓ Branch 2 taken 23 times.
64563 if (match_LogNot_14(nodep)) return;
6718 64540 if (match_LogNot_15(nodep)) return;
6719 }
6720 // Generated by astgen with short-circuiting
6721 8396 void visit(AstLogOr* nodep) override {
6722
1/2
✓ Branch 0 taken 8396 times.
✗ Branch 1 not taken.
8396 iterateAndNextNull(nodep->lhsp());
6723
2/2
✓ Branch 1 taken 7738 times.
✓ Branch 2 taken 658 times.
8396 if (match_LogOr_0(nodep)) return;
6724 iterateAndNextNull(nodep->rhsp());
6725
2/2
✓ Branch 1 taken 7635 times.
✓ Branch 2 taken 103 times.
7738 if (match_NodeBiop_0(nodep)) return;
6726
2/2
✓ Branch 1 taken 7577 times.
✓ Branch 2 taken 58 times.
7635 if (match_LogOr_1(nodep)) return;
6727
2/2
✓ Branch 1 taken 7522 times.
✓ Branch 2 taken 55 times.
7577 if (match_LogOr_2(nodep)) return;
6728
1/2
✓ Branch 1 taken 7522 times.
✗ Branch 2 not taken.
7522 if (match_LogOr_3(nodep)) return;
6729
2/2
✓ Branch 1 taken 7153 times.
✓ Branch 2 taken 369 times.
7522 if (match_LogOr_4(nodep)) return;
6730
1/2
✓ Branch 1 taken 7153 times.
✗ Branch 2 not taken.
7153 if (match_LogOr_5(nodep)) return;
6731 7153 if (match_LogOr_6(nodep)) return;
6732 }
6733 // Generated by astgen
6734 53062 void visit(AstLt* nodep) override {
6735 53062 iterateChildren(nodep);
6736
2/2
✓ Branch 1 taken 53032 times.
✓ Branch 2 taken 30 times.
53062 if (match_Lt_2(nodep)) return;
6737
2/2
✓ Branch 1 taken 52848 times.
✓ Branch 2 taken 184 times.
53032 if (match_Lt_1(nodep)) return;
6738
2/2
✓ Branch 1 taken 52510 times.
✓ Branch 2 taken 338 times.
52848 if (match_NodeBiop_0(nodep)) return;
6739
2/2
✓ Branch 1 taken 52157 times.
✓ Branch 2 taken 353 times.
52510 if (match_Lt_0(nodep)) return;
6740
2/2
✓ Branch 1 taken 52033 times.
✓ Branch 2 taken 124 times.
52157 if (match_Lt_3(nodep)) return;
6741
2/2
✓ Branch 1 taken 51793 times.
✓ Branch 2 taken 240 times.
52033 if (match_Lt_4(nodep)) return;
6742
2/2
✓ Branch 1 taken 51761 times.
✓ Branch 2 taken 32 times.
51793 if (match_Lt_5(nodep)) return;
6743 51761 if (match_Lt_6(nodep)) return;
6744 }
6745 // Generated by astgen
6746 void visit(AstLtD* nodep) override {
6747 iterateChildren(nodep);
6748 if (match_NodeBiop_0(nodep)) return;
6749 if (match_LtD_0(nodep)) return;
6750 }
6751 // Generated by astgen
6752 void visit(AstLtN* nodep) override {
6753 iterateChildren(nodep);
6754 if (match_NodeBiop_0(nodep)) return;
6755 if (match_LtN_0(nodep)) return;
6756 }
6757 // Generated by astgen
6758 3559 void visit(AstLtS* nodep) override {
6759 3559 iterateChildren(nodep);
6760
2/2
✓ Branch 1 taken 3555 times.
✓ Branch 2 taken 4 times.
3559 if (match_NodeBiop_0(nodep)) return;
6761
2/2
✓ Branch 1 taken 3532 times.
✓ Branch 2 taken 23 times.
3555 if (match_LtS_0(nodep)) return;
6762 3532 if (match_LtS_1(nodep)) return;
6763 }
6764 // Generated by astgen
6765 40653 void visit(AstLte* nodep) override {
6766 40653 iterateChildren(nodep);
6767
2/2
✓ Branch 1 taken 40619 times.
✓ Branch 2 taken 34 times.
40653 if (match_Lte_2(nodep)) return;
6768
2/2
✓ Branch 1 taken 40415 times.
✓ Branch 2 taken 204 times.
40619 if (match_Lte_1(nodep)) return;
6769
2/2
✓ Branch 1 taken 40096 times.
✓ Branch 2 taken 319 times.
40415 if (match_NodeBiop_0(nodep)) return;
6770
2/2
✓ Branch 1 taken 39630 times.
✓ Branch 2 taken 466 times.
40096 if (match_Lte_0(nodep)) return;
6771
2/2
✓ Branch 1 taken 39601 times.
✓ Branch 2 taken 29 times.
39630 if (match_Lte_3(nodep)) return;
6772
2/2
✓ Branch 1 taken 39343 times.
✓ Branch 2 taken 258 times.
39601 if (match_Lte_4(nodep)) return;
6773
2/2
✓ Branch 1 taken 39308 times.
✓ Branch 2 taken 35 times.
39343 if (match_Lte_5(nodep)) return;
6774 39308 if (match_Lte_6(nodep)) return;
6775 }
6776 // Generated by astgen
6777 void visit(AstLteD* nodep) override {
6778 iterateChildren(nodep);
6779 if (match_NodeBiop_0(nodep)) return;
6780 if (match_LteD_0(nodep)) return;
6781 }
6782 // Generated by astgen
6783 void visit(AstLteN* nodep) override {
6784 iterateChildren(nodep);
6785 if (match_NodeBiop_0(nodep)) return;
6786 if (match_LteN_0(nodep)) return;
6787 }
6788 // Generated by astgen
6789 3547 void visit(AstLteS* nodep) override {
6790 3547 iterateChildren(nodep);
6791
2/2
✓ Branch 1 taken 3542 times.
✓ Branch 2 taken 5 times.
3547 if (match_NodeBiop_0(nodep)) return;
6792
2/2
✓ Branch 1 taken 3524 times.
✓ Branch 2 taken 18 times.
3542 if (match_LteS_0(nodep)) return;
6793 3524 if (match_LteS_1(nodep)) return;
6794 }
6795 // Generated by astgen
6796 void visit(AstModDiv* nodep) override {
6797 iterateChildren(nodep);
6798 if (match_NodeBiop_0(nodep)) return;
6799 if (match_ModDiv_0(nodep)) return;
6800 }
6801 // Generated by astgen
6802 void visit(AstModDivS* nodep) override {
6803 iterateChildren(nodep);
6804 if (match_NodeBiop_0(nodep)) return;
6805 }
6806 // Generated by astgen
6807 42090 void visit(AstMul* nodep) override {
6808 42090 iterateChildren(nodep);
6809
2/2
✓ Branch 1 taken 41621 times.
✓ Branch 2 taken 469 times.
42090 if (match_NodeBiop_0(nodep)) return;
6810
2/2
✓ Branch 1 taken 41190 times.
✓ Branch 2 taken 431 times.
41621 if (match_NodeBiCom_0(nodep)) return;
6811
1/2
✓ Branch 1 taken 41190 times.
✗ Branch 2 not taken.
41190 if (match_NodeBiComAsv_0(nodep)) return;
6812
1/2
✓ Branch 1 taken 41190 times.
✗ Branch 2 not taken.
41190 if (match_NodeBiComAsv_1(nodep)) return;
6813
2/2
✓ Branch 1 taken 41186 times.
✓ Branch 2 taken 4 times.
41190 if (match_NodeBiComAsv_2(nodep)) return;
6814
2/2
✓ Branch 1 taken 41184 times.
✓ Branch 2 taken 2 times.
41186 if (match_NodeBiComAsv_3(nodep)) return;
6815
2/2
✓ Branch 1 taken 40984 times.
✓ Branch 2 taken 200 times.
41184 if (match_Mul_0(nodep)) return;
6816
1/2
✓ Branch 1 taken 40984 times.
✗ Branch 2 not taken.
40984 if (match_Mul_1(nodep)) return;
6817
2/2
✓ Branch 1 taken 40872 times.
✓ Branch 2 taken 112 times.
40984 if (match_Mul_2(nodep)) return;
6818 40872 if (match_Mul_3(nodep)) return;
6819 }
6820 // Generated by astgen
6821 void visit(AstMulD* nodep) override {
6822 iterateChildren(nodep);
6823 if (match_NodeBiop_0(nodep)) return;
6824 if (match_NodeBiCom_0(nodep)) return;
6825 if (match_NodeBiComAsv_0(nodep)) return;
6826 if (match_NodeBiComAsv_1(nodep)) return;
6827 if (match_NodeBiComAsv_2(nodep)) return;
6828 if (match_NodeBiComAsv_3(nodep)) return;
6829 }
6830 // Generated by astgen
6831 2869 void visit(AstMulS* nodep) override {
6832 2869 iterateChildren(nodep);
6833
2/2
✓ Branch 1 taken 2867 times.
✓ Branch 2 taken 2 times.
2869 if (match_NodeBiop_0(nodep)) return;
6834
2/2
✓ Branch 1 taken 2853 times.
✓ Branch 2 taken 14 times.
2867 if (match_NodeBiCom_0(nodep)) return;
6835
1/2
✓ Branch 1 taken 2853 times.
✗ Branch 2 not taken.
2853 if (match_NodeBiComAsv_0(nodep)) return;
6836
1/2
✓ Branch 1 taken 2853 times.
✗ Branch 2 not taken.
2853 if (match_NodeBiComAsv_1(nodep)) return;
6837
1/2
✓ Branch 1 taken 2853 times.
✗ Branch 2 not taken.
2853 if (match_NodeBiComAsv_2(nodep)) return;
6838
1/2
✓ Branch 1 taken 2853 times.
✗ Branch 2 not taken.
2853 if (match_NodeBiComAsv_3(nodep)) return;
6839
2/2
✓ Branch 1 taken 2842 times.
✓ Branch 2 taken 11 times.
2853 if (match_MulS_0(nodep)) return;
6840
1/2
✓ Branch 1 taken 2842 times.
✗ Branch 2 not taken.
2842 if (match_MulS_1(nodep)) return;
6841 2842 if (match_MulS_2(nodep)) return;
6842 }
6843 // Generated by astgen
6844 void visit(AstNToI* nodep) override {
6845 iterateChildren(nodep);
6846 if (match_NodeUniop_0(nodep)) return;
6847 }
6848 // Generated by astgen
6849 84713 void visit(AstNegate* nodep) override {
6850 84713 iterateChildren(nodep);
6851 84713 if (match_NodeUniop_0(nodep)) return;
6852 }
6853 // Generated by astgen
6854 void visit(AstNegateD* nodep) override {
6855 iterateChildren(nodep);
6856 if (match_NodeUniop_0(nodep)) return;
6857 }
6858 // Generated by astgen
6859 148951 void visit(AstNeq* nodep) override {
6860 148951 iterateChildren(nodep);
6861
2/2
✓ Branch 1 taken 148413 times.
✓ Branch 2 taken 538 times.
148951 if (match_NodeBiop_0(nodep)) return;
6862
2/2
✓ Branch 1 taken 147925 times.
✓ Branch 2 taken 488 times.
148413 if (match_NodeBiCom_0(nodep)) return;
6863
2/2
✓ Branch 1 taken 147836 times.
✓ Branch 2 taken 89 times.
147925 if (match_Neq_0(nodep)) return;
6864
2/2
✓ Branch 1 taken 147594 times.
✓ Branch 2 taken 242 times.
147836 if (match_Neq_1(nodep)) return;
6865
2/2
✓ Branch 1 taken 147529 times.
✓ Branch 2 taken 65 times.
147594 if (match_Neq_2(nodep)) return;
6866
2/2
✓ Branch 1 taken 147485 times.
✓ Branch 2 taken 44 times.
147529 if (match_Neq_3(nodep)) return;
6867
1/2
✓ Branch 1 taken 147485 times.
✗ Branch 2 not taken.
147485 if (match_Neq_4(nodep)) return;
6868
2/2
✓ Branch 1 taken 147457 times.
✓ Branch 2 taken 28 times.
147485 if (match_Neq_5(nodep)) return;
6869 147457 if (match_Neq_6(nodep)) return;
6870 }
6871 // Generated by astgen
6872 void visit(AstNeqCase* nodep) override {
6873 iterateChildren(nodep);
6874 if (match_NodeBiop_0(nodep)) return;
6875 if (match_NodeBiCom_0(nodep)) return;
6876 if (match_NeqCase_0(nodep)) return;
6877 }
6878 // Generated by astgen
6879 void visit(AstNeqD* nodep) override {
6880 iterateChildren(nodep);
6881 if (match_NodeBiop_0(nodep)) return;
6882 if (match_NodeBiCom_0(nodep)) return;
6883 if (match_NeqD_0(nodep)) return;
6884 }
6885 // Generated by astgen
6886 void visit(AstNeqN* nodep) override {
6887 iterateChildren(nodep);
6888 if (match_NodeBiop_0(nodep)) return;
6889 if (match_NodeBiCom_0(nodep)) return;
6890 if (match_NeqN_0(nodep)) return;
6891 }
6892 // Generated by astgen
6893 void visit(AstNeqT* nodep) override {
6894 iterateChildren(nodep);
6895 if (match_NodeBiop_0(nodep)) return;
6896 if (match_NodeBiCom_0(nodep)) return;
6897 }
6898 // Generated by astgen
6899 void visit(AstNeqWild* nodep) override {
6900 iterateChildren(nodep);
6901 if (match_NodeBiop_0(nodep)) return;
6902 if (match_NeqWild_0(nodep)) return;
6903 }
6904 // Generated by astgen
6905 void visit(AstNodeBiCom* nodep) override {
6906 iterateChildren(nodep);
6907 if (match_NodeBiop_0(nodep)) return;
6908 if (match_NodeBiCom_0(nodep)) return;
6909 }
6910 // Generated by astgen
6911 void visit(AstNodeBiComAsv* nodep) override {
6912 iterateChildren(nodep);
6913 if (match_NodeBiop_0(nodep)) return;
6914 if (match_NodeBiCom_0(nodep)) return;
6915 if (match_NodeBiComAsv_0(nodep)) return;
6916 if (match_NodeBiComAsv_1(nodep)) return;
6917 if (match_NodeBiComAsv_2(nodep)) return;
6918 if (match_NodeBiComAsv_3(nodep)) return;
6919 }
6920 // Generated by astgen
6921 void visit(AstNodeBiop* nodep) override {
6922 iterateChildren(nodep);
6923 if (match_NodeBiop_0(nodep)) return;
6924 }
6925 // Generated by astgen
6926 void visit(AstNodeCond* nodep) override {
6927 iterateChildren(nodep);
6928 if (match_NodeCond_0(nodep)) return;
6929 if (match_NodeCond_1(nodep)) return;
6930 if (match_NodeCond_2(nodep)) return;
6931 if (match_NodeCond_3(nodep)) return;
6932 if (match_NodeCond_4(nodep)) return;
6933 if (match_NodeCond_5(nodep)) return;
6934 if (match_NodeCond_6(nodep)) return;
6935 if (match_NodeCond_7(nodep)) return;
6936 if (match_NodeCond_8(nodep)) return;
6937 if (match_NodeCond_9(nodep)) return;
6938 }
6939 // Generated by astgen
6940 void visit(AstNodeDistBiop* nodep) override {
6941 iterateChildren(nodep);
6942 if (match_NodeBiop_0(nodep)) return;
6943 }
6944 // Generated by astgen
6945 void visit(AstNodeQuadop* nodep) override {
6946 iterateChildren(nodep);
6947 if (match_NodeQuadop_0(nodep)) return;
6948 }
6949 // Generated by astgen
6950 void visit(AstNodeSel* nodep) override {
6951 iterateChildren(nodep);
6952 if (match_NodeBiop_0(nodep)) return;
6953 }
6954 // Generated by astgen
6955 void visit(AstNodeStream* nodep) override {
6956 iterateChildren(nodep);
6957 if (match_NodeBiop_0(nodep)) return;
6958 }
6959 // Generated by astgen
6960 void visit(AstNodeSystemBiopD* nodep) override {
6961 iterateChildren(nodep);
6962 if (match_NodeBiop_0(nodep)) return;
6963 }
6964 // Generated by astgen
6965 void visit(AstNodeSystemUniopD* nodep) override {
6966 iterateChildren(nodep);
6967 if (match_NodeUniop_0(nodep)) return;
6968 }
6969 // Generated by astgen
6970 void visit(AstNodeUniop* nodep) override {
6971 iterateChildren(nodep);
6972 if (match_NodeUniop_0(nodep)) return;
6973 }
6974 // Generated by astgen
6975 471131 void visit(AstNot* nodep) override {
6976 471131 iterateChildren(nodep);
6977
2/2
✓ Branch 1 taken 467567 times.
✓ Branch 2 taken 3564 times.
471131 if (match_NodeUniop_0(nodep)) return;
6978
2/2
✓ Branch 1 taken 465304 times.
✓ Branch 2 taken 2263 times.
467567 if (match_Not_0(nodep)) return;
6979
1/2
✓ Branch 1 taken 465304 times.
✗ Branch 2 not taken.
465304 if (match_Not_1(nodep)) return;
6980
1/2
✓ Branch 1 taken 465304 times.
✗ Branch 2 not taken.
465304 if (match_Not_2(nodep)) return;
6981
1/2
✓ Branch 1 taken 465304 times.
✗ Branch 2 not taken.
465304 if (match_Not_3(nodep)) return;
6982
1/2
✓ Branch 1 taken 465304 times.
✗ Branch 2 not taken.
465304 if (match_Not_4(nodep)) return;
6983
2/2
✓ Branch 1 taken 465270 times.
✓ Branch 2 taken 34 times.
465304 if (match_Not_5(nodep)) return;
6984
2/2
✓ Branch 1 taken 465235 times.
✓ Branch 2 taken 35 times.
465270 if (match_Not_6(nodep)) return;
6985
2/2
✓ Branch 1 taken 465193 times.
✓ Branch 2 taken 42 times.
465235 if (match_Not_7(nodep)) return;
6986
2/2
✓ Branch 1 taken 465187 times.
✓ Branch 2 taken 6 times.
465193 if (match_Not_8(nodep)) return;
6987
2/2
✓ Branch 1 taken 465156 times.
✓ Branch 2 taken 31 times.
465187 if (match_Not_9(nodep)) return;
6988
2/2
✓ Branch 1 taken 465149 times.
✓ Branch 2 taken 7 times.
465156 if (match_Not_10(nodep)) return;
6989
2/2
✓ Branch 1 taken 465114 times.
✓ Branch 2 taken 35 times.
465149 if (match_Not_11(nodep)) return;
6990
2/2
✓ Branch 1 taken 465111 times.
✓ Branch 2 taken 3 times.
465114 if (match_Not_12(nodep)) return;
6991
2/2
✓ Branch 1 taken 465073 times.
✓ Branch 2 taken 38 times.
465111 if (match_Not_13(nodep)) return;
6992 465073 if (match_Not_14(nodep)) return;
6993 }
6994 // Generated by astgen
6995 void visit(AstNullCheck* nodep) override {
6996 iterateChildren(nodep);
6997 if (match_NodeUniop_0(nodep)) return;
6998 }
6999 // Generated by astgen
7000 void visit(AstOneHot* nodep) override {
7001 iterateChildren(nodep);
7002 if (match_NodeUniop_0(nodep)) return;
7003 if (match_OneHot_0(nodep)) return;
7004 }
7005 // Generated by astgen
7006 void visit(AstOneHot0* nodep) override {
7007 iterateChildren(nodep);
7008 if (match_NodeUniop_0(nodep)) return;
7009 if (match_OneHot0_0(nodep)) return;
7010 }
7011 // Generated by astgen
7012 653217 void visit(AstOr* nodep) override {
7013 653217 iterateChildren(nodep);
7014
2/2
✓ Branch 1 taken 622646 times.
✓ Branch 2 taken 30571 times.
653217 if (match_NodeBiop_0(nodep)) return;
7015
2/2
✓ Branch 1 taken 596127 times.
✓ Branch 2 taken 26519 times.
622646 if (match_NodeBiCom_0(nodep)) return;
7016
2/2
✓ Branch 1 taken 596073 times.
✓ Branch 2 taken 54 times.
596127 if (match_NodeBiComAsv_0(nodep)) return;
7017
2/2
✓ Branch 1 taken 596069 times.
✓ Branch 2 taken 4 times.
596073 if (match_NodeBiComAsv_1(nodep)) return;
7018
2/2
✓ Branch 1 taken 595983 times.
✓ Branch 2 taken 86 times.
596069 if (match_NodeBiComAsv_2(nodep)) return;
7019
2/2
✓ Branch 1 taken 595336 times.
✓ Branch 2 taken 647 times.
595983 if (match_NodeBiComAsv_3(nodep)) return;
7020
2/2
✓ Branch 1 taken 519722 times.
✓ Branch 2 taken 75614 times.
595336 if (match_Or_0(nodep)) return;
7021
1/2
✓ Branch 1 taken 519722 times.
✗ Branch 2 not taken.
519722 if (match_Or_1(nodep)) return;
7022
2/2
✓ Branch 1 taken 518421 times.
✓ Branch 2 taken 1301 times.
519722 if (match_Or_2(nodep)) return;
7023
1/2
✓ Branch 1 taken 518421 times.
✗ Branch 2 not taken.
518421 if (match_Or_3(nodep)) return;
7024
2/2
✓ Branch 1 taken 518298 times.
✓ Branch 2 taken 123 times.
518421 if (match_Or_4(nodep)) return;
7025
2/2
✓ Branch 1 taken 517664 times.
✓ Branch 2 taken 634 times.
518298 if (match_Or_5(nodep)) return;
7026
1/2
✓ Branch 1 taken 517664 times.
✗ Branch 2 not taken.
517664 if (match_Or_6(nodep)) return;
7027
2/2
✓ Branch 1 taken 517290 times.
✓ Branch 2 taken 374 times.
517664 if (match_Or_7(nodep)) return;
7028 517290 if (match_Or_8(nodep)) return;
7029 }
7030 // Generated by astgen
7031 void visit(AstPow* nodep) override {
7032 iterateChildren(nodep);
7033 if (match_NodeBiop_0(nodep)) return;
7034 if (match_Pow_0(nodep)) return;
7035 if (match_Pow_1(nodep)) return;
7036 }
7037 // Generated by astgen
7038 void visit(AstPowD* nodep) override {
7039 iterateChildren(nodep);
7040 if (match_NodeBiop_0(nodep)) return;
7041 }
7042 // Generated by astgen
7043 void visit(AstPowSS* nodep) override {
7044 iterateChildren(nodep);
7045 if (match_NodeBiop_0(nodep)) return;
7046 if (match_PowSS_0(nodep)) return;
7047 }
7048 // Generated by astgen
7049 void visit(AstPowSU* nodep) override {
7050 iterateChildren(nodep);
7051 if (match_NodeBiop_0(nodep)) return;
7052 if (match_PowSU_0(nodep)) return;
7053 }
7054 // Generated by astgen
7055 void visit(AstPowUS* nodep) override {
7056 iterateChildren(nodep);
7057 if (match_NodeBiop_0(nodep)) return;
7058 if (match_PowUS_0(nodep)) return;
7059 }
7060 // Generated by astgen
7061 void visit(AstPutcN* nodep) override {
7062 iterateChildren(nodep);
7063 if (match_PutcN_0(nodep)) return;
7064 }
7065 // Generated by astgen
7066 void visit(AstRToIRoundS* nodep) override {
7067 iterateChildren(nodep);
7068 if (match_NodeUniop_0(nodep)) return;
7069 }
7070 // Generated by astgen
7071 void visit(AstRToIS* nodep) override {
7072 iterateChildren(nodep);
7073 if (match_NodeUniop_0(nodep)) return;
7074 }
7075 // Generated by astgen
7076 void visit(AstRealToBits* nodep) override {
7077 iterateChildren(nodep);
7078 if (match_NodeUniop_0(nodep)) return;
7079 }
7080 // Generated by astgen
7081 129985 void visit(AstRedAnd* nodep) override {
7082 129985 iterateChildren(nodep);
7083
2/2
✓ Branch 1 taken 126619 times.
✓ Branch 2 taken 3366 times.
129985 if (match_NodeUniop_0(nodep)) return;
7084
2/2
✓ Branch 1 taken 124121 times.
✓ Branch 2 taken 2498 times.
126619 if (match_RedAnd_0(nodep)) return;
7085
2/2
✓ Branch 1 taken 123441 times.
✓ Branch 2 taken 680 times.
124121 if (match_RedAnd_1(nodep)) return;
7086 123441 if (match_RedAnd_2(nodep)) return;
7087 }
7088 // Generated by astgen
7089 1021989 void visit(AstRedOr* nodep) override {
7090 1021989 iterateChildren(nodep);
7091
2/2
✓ Branch 1 taken 1007405 times.
✓ Branch 2 taken 14584 times.
1021989 if (match_NodeUniop_0(nodep)) return;
7092
2/2
✓ Branch 1 taken 1000270 times.
✓ Branch 2 taken 7135 times.
1007405 if (match_RedOr_0(nodep)) return;
7093
2/2
✓ Branch 1 taken 994135 times.
✓ Branch 2 taken 6135 times.
1000270 if (match_RedOr_1(nodep)) return;
7094 994135 if (match_RedOr_2(nodep)) return;
7095 }
7096 // Generated by astgen
7097 223231 void visit(AstRedXor* nodep) override {
7098 223231 iterateChildren(nodep);
7099
2/2
✓ Branch 1 taken 217979 times.
✓ Branch 2 taken 5252 times.
223231 if (match_NodeUniop_0(nodep)) return;
7100
2/2
✓ Branch 1 taken 213768 times.
✓ Branch 2 taken 4211 times.
217979 if (match_RedXor_0(nodep)) return;
7101
2/2
✓ Branch 1 taken 212769 times.
✓ Branch 2 taken 999 times.
213768 if (match_RedXor_1(nodep)) return;
7102
2/2
✓ Branch 1 taken 211744 times.
✓ Branch 2 taken 1025 times.
212769 if (match_RedXor_2(nodep)) return;
7103 211744 if (match_RedXor_3(nodep)) return;
7104 }
7105 // Generated by astgen
7106 104402 void visit(AstReplicate* nodep) override {
7107 104402 iterateChildren(nodep);
7108
2/2
✓ Branch 1 taken 97022 times.
✓ Branch 2 taken 7380 times.
104402 if (match_NodeBiop_0(nodep)) return;
7109
2/2
✓ Branch 1 taken 51322 times.
✓ Branch 2 taken 45700 times.
97022 if (match_Replicate_0(nodep)) return;
7110 51322 if (match_Replicate_1(nodep)) return;
7111 }
7112 // Generated by astgen
7113 void visit(AstReplicateN* nodep) override {
7114 iterateChildren(nodep);
7115 if (match_NodeBiop_0(nodep)) return;
7116 if (match_ReplicateN_0(nodep)) return;
7117 }
7118 // Generated by astgen
7119 void visit(AstResizeLValue* nodep) override {
7120 iterateChildren(nodep);
7121 if (match_NodeUniop_0(nodep)) return;
7122 }
7123 // Generated by astgen
7124 1344563 void visit(AstSel* nodep) override {
7125 1344563 iterateChildren(nodep);
7126
1/2
✓ Branch 1 taken 1344563 times.
✗ Branch 2 not taken.
1344563 if (match_Sel_0(nodep)) return;
7127
1/2
✓ Branch 1 taken 1344563 times.
✗ Branch 2 not taken.
1344563 if (match_Sel_1(nodep)) return;
7128
2/2
✓ Branch 1 taken 1343846 times.
✓ Branch 2 taken 717 times.
1344563 if (match_Sel_2(nodep)) return;
7129
2/2
✓ Branch 1 taken 1334219 times.
✓ Branch 2 taken 9627 times.
1343846 if (match_Sel_3(nodep)) return;
7130
2/2
✓ Branch 1 taken 1323190 times.
✓ Branch 2 taken 11029 times.
1334219 if (match_Sel_4(nodep)) return;
7131
2/2
✓ Branch 1 taken 1322652 times.
✓ Branch 2 taken 538 times.
1323190 if (match_Sel_5(nodep)) return;
7132
2/2
✓ Branch 1 taken 1322104 times.
✓ Branch 2 taken 548 times.
1322652 if (match_Sel_6(nodep)) return;
7133
2/2
✓ Branch 1 taken 1321565 times.
✓ Branch 2 taken 539 times.
1322104 if (match_Sel_7(nodep)) return;
7134
2/2
✓ Branch 1 taken 1321071 times.
✓ Branch 2 taken 494 times.
1321565 if (match_Sel_8(nodep)) return;
7135
2/2
✓ Branch 1 taken 1319430 times.
✓ Branch 2 taken 1641 times.
1321071 if (match_Sel_9(nodep)) return;
7136
2/2
✓ Branch 1 taken 1319416 times.
✓ Branch 2 taken 14 times.
1319430 if (match_Sel_10(nodep)) return;
7137
2/2
✓ Branch 1 taken 1313232 times.
✓ Branch 2 taken 6184 times.
1319416 if (match_Sel_11(nodep)) return;
7138
2/2
✓ Branch 1 taken 1298930 times.
✓ Branch 2 taken 14302 times.
1313232 if (match_Sel_12(nodep)) return;
7139
2/2
✓ Branch 1 taken 1298914 times.
✓ Branch 2 taken 16 times.
1298930 if (match_Sel_13(nodep)) return;
7140
1/2
✓ Branch 1 taken 1298914 times.
✗ Branch 2 not taken.
1298914 if (match_Sel_14(nodep)) return;
7141
2/2
✓ Branch 1 taken 1296911 times.
✓ Branch 2 taken 2003 times.
1298914 if (match_Sel_15(nodep)) return;
7142
2/2
✓ Branch 1 taken 1296902 times.
✓ Branch 2 taken 9 times.
1296911 if (match_Sel_16(nodep)) return;
7143
2/2
✓ Branch 1 taken 1296881 times.
✓ Branch 2 taken 21 times.
1296902 if (match_Sel_17(nodep)) return;
7144 1296881 if (match_Sel_18(nodep)) return;
7145 }
7146 // Generated by astgen
7147 642167 void visit(AstShiftL* nodep) override {
7148 642167 iterateChildren(nodep);
7149
2/2
✓ Branch 1 taken 590211 times.
✓ Branch 2 taken 51956 times.
642167 if (match_NodeBiop_0(nodep)) return;
7150
2/2
✓ Branch 1 taken 589969 times.
✓ Branch 2 taken 242 times.
590211 if (match_ShiftL_0(nodep)) return;
7151
2/2
✓ Branch 1 taken 589496 times.
✓ Branch 2 taken 473 times.
589969 if (match_ShiftL_1(nodep)) return;
7152
2/2
✓ Branch 1 taken 586452 times.
✓ Branch 2 taken 3044 times.
589496 if (match_ShiftL_2(nodep)) return;
7153
2/2
✓ Branch 1 taken 563117 times.
✓ Branch 2 taken 23335 times.
586452 if (match_ShiftL_3(nodep)) return;
7154 563117 if (match_ShiftL_4(nodep)) return;
7155 }
7156 // Generated by astgen
7157 7861 void visit(AstShiftLOvr* nodep) override {
7158 7861 iterateChildren(nodep);
7159
1/2
✓ Branch 1 taken 7861 times.
✗ Branch 2 not taken.
7861 if (match_NodeBiop_0(nodep)) return;
7160
2/2
✓ Branch 1 taken 7856 times.
✓ Branch 2 taken 5 times.
7861 if (match_ShiftLOvr_0(nodep)) return;
7161
2/2
✓ Branch 1 taken 7854 times.
✓ Branch 2 taken 2 times.
7856 if (match_ShiftLOvr_1(nodep)) return;
7162 7854 if (match_ShiftLOvr_2(nodep)) return;
7163 }
7164 // Generated by astgen
7165 395288 void visit(AstShiftR* nodep) override {
7166 395288 iterateChildren(nodep);
7167
2/2
✓ Branch 1 taken 351586 times.
✓ Branch 2 taken 43702 times.
395288 if (match_NodeBiop_0(nodep)) return;
7168
2/2
✓ Branch 1 taken 351345 times.
✓ Branch 2 taken 241 times.
351586 if (match_ShiftR_0(nodep)) return;
7169
2/2
✓ Branch 1 taken 315944 times.
✓ Branch 2 taken 35401 times.
351345 if (match_ShiftR_1(nodep)) return;
7170
2/2
✓ Branch 1 taken 314841 times.
✓ Branch 2 taken 1103 times.
315944 if (match_ShiftR_2(nodep)) return;
7171
2/2
✓ Branch 1 taken 305383 times.
✓ Branch 2 taken 9458 times.
314841 if (match_ShiftR_3(nodep)) return;
7172 305383 if (match_ShiftR_4(nodep)) return;
7173 }
7174 // Generated by astgen
7175 4668 void visit(AstShiftROvr* nodep) override {
7176 4668 iterateChildren(nodep);
7177
1/2
✓ Branch 1 taken 4668 times.
✗ Branch 2 not taken.
4668 if (match_NodeBiop_0(nodep)) return;
7178
2/2
✓ Branch 1 taken 4666 times.
✓ Branch 2 taken 2 times.
4668 if (match_ShiftROvr_0(nodep)) return;
7179
2/2
✓ Branch 1 taken 4663 times.
✓ Branch 2 taken 3 times.
4666 if (match_ShiftROvr_1(nodep)) return;
7180 4663 if (match_ShiftROvr_2(nodep)) return;
7181 }
7182 // Generated by astgen
7183 9093 void visit(AstShiftRS* nodep) override {
7184 9093 iterateChildren(nodep);
7185
2/2
✓ Branch 1 taken 9076 times.
✓ Branch 2 taken 17 times.
9093 if (match_NodeBiop_0(nodep)) return;
7186
2/2
✓ Branch 1 taken 9051 times.
✓ Branch 2 taken 25 times.
9076 if (match_ShiftRS_0(nodep)) return;
7187 9051 if (match_ShiftRS_1(nodep)) return;
7188 }
7189 // Generated by astgen
7190 659 void visit(AstShiftRSOvr* nodep) override {
7191 659 iterateChildren(nodep);
7192
1/2
✓ Branch 1 taken 659 times.
✗ Branch 2 not taken.
659 if (match_NodeBiop_0(nodep)) return;
7193
1/2
✓ Branch 1 taken 659 times.
✗ Branch 2 not taken.
659 if (match_ShiftRSOvr_0(nodep)) return;
7194 659 if (match_ShiftRSOvr_1(nodep)) return;
7195 }
7196 // Generated by astgen
7197 void visit(AstSigned* nodep) override {
7198 iterateChildren(nodep);
7199 if (match_NodeUniop_0(nodep)) return;
7200 }
7201 // Generated by astgen
7202 void visit(AstSinD* nodep) override {
7203 iterateChildren(nodep);
7204 if (match_NodeUniop_0(nodep)) return;
7205 }
7206 // Generated by astgen
7207 void visit(AstSinhD* nodep) override {
7208 iterateChildren(nodep);
7209 if (match_NodeUniop_0(nodep)) return;
7210 }
7211 // Generated by astgen
7212 void visit(AstSqrtD* nodep) override {
7213 iterateChildren(nodep);
7214 if (match_NodeUniop_0(nodep)) return;
7215 }
7216 // Generated by astgen
7217 void visit(AstStreamL* nodep) override {
7218 iterateChildren(nodep);
7219 if (match_NodeBiop_0(nodep)) return;
7220 }
7221 // Generated by astgen
7222 void visit(AstStreamR* nodep) override {
7223 iterateChildren(nodep);
7224 if (match_NodeBiop_0(nodep)) return;
7225 }
7226 // Generated by astgen
7227 46386 void visit(AstSub* nodep) override {
7228 46386 iterateChildren(nodep);
7229
2/2
✓ Branch 1 taken 45978 times.
✓ Branch 2 taken 408 times.
46386 if (match_NodeBiop_0(nodep)) return;
7230
2/2
✓ Branch 1 taken 45858 times.
✓ Branch 2 taken 120 times.
45978 if (match_Sub_0(nodep)) return;
7231
2/2
✓ Branch 1 taken 45757 times.
✓ Branch 2 taken 101 times.
45858 if (match_Sub_1(nodep)) return;
7232
2/2
✓ Branch 1 taken 45756 times.
✓ Branch 2 taken 1 times.
45757 if (match_Sub_2(nodep)) return;
7233 45756 if (match_Sub_3(nodep)) return;
7234 }
7235 // Generated by astgen
7236 void visit(AstSubD* nodep) override {
7237 iterateChildren(nodep);
7238 if (match_NodeBiop_0(nodep)) return;
7239 }
7240 // Generated by astgen
7241 void visit(AstSubstrN* nodep) override {
7242 iterateChildren(nodep);
7243 if (match_SubstrN_0(nodep)) return;
7244 }
7245 // Generated by astgen
7246 void visit(AstTanD* nodep) override {
7247 iterateChildren(nodep);
7248 if (match_NodeUniop_0(nodep)) return;
7249 }
7250 // Generated by astgen
7251 void visit(AstTanhD* nodep) override {
7252 iterateChildren(nodep);
7253 if (match_NodeUniop_0(nodep)) return;
7254 }
7255 // Generated by astgen
7256 void visit(AstTimeImport* nodep) override {
7257 iterateChildren(nodep);
7258 if (match_NodeUniop_0(nodep)) return;
7259 }
7260 // Generated by astgen
7261 void visit(AstToLowerN* nodep) override {
7262 iterateChildren(nodep);
7263 if (match_NodeUniop_0(nodep)) return;
7264 }
7265 // Generated by astgen
7266 void visit(AstToUpperN* nodep) override {
7267 iterateChildren(nodep);
7268 if (match_NodeUniop_0(nodep)) return;
7269 }
7270 // Generated by astgen
7271 void visit(AstURandomRange* nodep) override {
7272 iterateChildren(nodep);
7273 if (match_NodeBiop_0(nodep)) return;
7274 }
7275 // Generated by astgen
7276 void visit(AstUnsigned* nodep) override {
7277 iterateChildren(nodep);
7278 if (match_NodeUniop_0(nodep)) return;
7279 }
7280 // Generated by astgen
7281 void visit(AstWildcardSel* nodep) override {
7282 iterateChildren(nodep);
7283 if (match_NodeBiop_0(nodep)) return;
7284 }
7285 // Generated by astgen
7286 279759 void visit(AstWordSel* nodep) override {
7287 279759 iterateChildren(nodep);
7288
1/2
✓ Branch 1 taken 279759 times.
✗ Branch 2 not taken.
279759 if (match_NodeBiop_0(nodep)) return;
7289 279759 if (match_WordSel_0(nodep)) return;
7290 }
7291 // Generated by astgen
7292 145851 void visit(AstXor* nodep) override {
7293 145851 iterateChildren(nodep);
7294
2/2
✓ Branch 1 taken 144509 times.
✓ Branch 2 taken 1342 times.
145851 if (match_NodeBiop_0(nodep)) return;
7295
2/2
✓ Branch 1 taken 142842 times.
✓ Branch 2 taken 1667 times.
144509 if (match_NodeBiCom_0(nodep)) return;
7296
2/2
✓ Branch 1 taken 142840 times.
✓ Branch 2 taken 2 times.
142842 if (match_NodeBiComAsv_0(nodep)) return;
7297
2/2
✓ Branch 1 taken 142839 times.
✓ Branch 2 taken 1 times.
142840 if (match_NodeBiComAsv_1(nodep)) return;
7298
2/2
✓ Branch 1 taken 142829 times.
✓ Branch 2 taken 10 times.
142839 if (match_NodeBiComAsv_2(nodep)) return;
7299
2/2
✓ Branch 1 taken 142818 times.
✓ Branch 2 taken 11 times.
142829 if (match_NodeBiComAsv_3(nodep)) return;
7300
2/2
✓ Branch 1 taken 141843 times.
✓ Branch 2 taken 975 times.
142818 if (match_Xor_0(nodep)) return;
7301
1/2
✓ Branch 1 taken 141843 times.
✗ Branch 2 not taken.
141843 if (match_Xor_1(nodep)) return;
7302
2/2
✓ Branch 1 taken 141663 times.
✓ Branch 2 taken 180 times.
141843 if (match_Xor_2(nodep)) return;
7303
2/2
✓ Branch 1 taken 141499 times.
✓ Branch 2 taken 164 times.
141663 if (match_Xor_3(nodep)) return;
7304
2/2
✓ Branch 1 taken 141352 times.
✓ Branch 2 taken 147 times.
141499 if (match_Xor_4(nodep)) return;
7305 141352 if (match_Xor_5(nodep)) return;
7306 }
7307 #line 3478 "../V3Const.cpp"
7308 // Generic constants on both side. Do this first to avoid other replacements
7309 // TREEOPA("AstNodeBiop {$lhsp.castConst, $rhsp.castConst, nodep->isPredictOptimizable()}", "replaceConst(nodep)");
7310 #line 7311 "V3Const__gen.cpp"
7311 #line 3480 "../V3Const.cpp"
7312 // TREEOPA("AstNodeUniop{$lhsp.castConst, !nodep->isOpaque(), nodep->isPredictOptimizable()}", "replaceConst(nodep)");
7313 #line 7314 "V3Const__gen.cpp"
7314 #line 3481 "../V3Const.cpp"
7315 // TREEOPA("AstNodeQuadop{$lhsp.castConst, $rhsp.castConst, $thsp.castConst, $fhsp.castConst}", "replaceConst(nodep)");
7316 #line 7317 "V3Const__gen.cpp"
7317 #line 3482 "../V3Const.cpp"
7318 // Zero on one side or the other
7319 // TREEOP ("AstAdd {$lhsp.isZero, $rhsp}", "replaceWRhs(nodep)");
7320 #line 7321 "V3Const__gen.cpp"
7321 #line 3484 "../V3Const.cpp"
7322 // TREEOP ("AstAnd {$lhsp.isZero, $rhsp, $rhsp.isPure}", "replaceZero(nodep)"); // Can't use replaceZeroChkPure as we make this pattern in ChkPure
7323 #line 7324 "V3Const__gen.cpp"
7324 #line 3485 "../V3Const.cpp"
7325 // This visit function here must allow for short-circuiting.
7326 // TREEOPS("AstLogAnd {$lhsp.isZero}", "replaceZero(nodep)");
7327 #line 7328 "V3Const__gen.cpp"
7328 #line 3487 "../V3Const.cpp"
7329 // TREEOP ("AstLogAnd{$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
7330 #line 7331 "V3Const__gen.cpp"
7331 #line 3488 "../V3Const.cpp"
7332 // This visit function here must allow for short-circuiting.
7333 // TREEOPS("AstLogOr {$lhsp.isOne}", "replaceNum(nodep, 1)");
7334 #line 7335 "V3Const__gen.cpp"
7335 #line 3490 "../V3Const.cpp"
7336 // TREEOP ("AstLogOr {$lhsp.isZero, $rhsp}", "replaceWRhsBool(nodep)");
7337 #line 7338 "V3Const__gen.cpp"
7338 #line 3491 "../V3Const.cpp"
7339 // TREEOP ("AstDiv {$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)");
7340 #line 7341 "V3Const__gen.cpp"
7341 #line 3492 "../V3Const.cpp"
7342 // TREEOP ("AstDivS {$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)");
7343 #line 7344 "V3Const__gen.cpp"
7344 #line 3493 "../V3Const.cpp"
7345 // TREEOP ("AstMul {$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)");
7346 #line 7347 "V3Const__gen.cpp"
7347 #line 3494 "../V3Const.cpp"
7348 // TREEOP ("AstMulS {$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)");
7349 #line 7350 "V3Const__gen.cpp"
7350 #line 3495 "../V3Const.cpp"
7351 // TREEOP ("AstPow {$rhsp.isZero}", "replaceNum(nodep, 1)"); // Overrides lhs zero rule
7352 #line 7353 "V3Const__gen.cpp"
7353 #line 3496 "../V3Const.cpp"
7354 // TREEOP ("AstPowSS {$rhsp.isZero}", "replaceNum(nodep, 1)"); // Overrides lhs zero rule
7355 #line 7356 "V3Const__gen.cpp"
7356 #line 3497 "../V3Const.cpp"
7357 // TREEOP ("AstPowSU {$rhsp.isZero}", "replaceNum(nodep, 1)"); // Overrides lhs zero rule
7358 #line 7359 "V3Const__gen.cpp"
7359 #line 3498 "../V3Const.cpp"
7360 // TREEOP ("AstPowUS {$rhsp.isZero}", "replaceNum(nodep, 1)"); // Overrides lhs zero rule
7361 #line 7362 "V3Const__gen.cpp"
7362 #line 3499 "../V3Const.cpp"
7363 // TREEOP ("AstOr {$lhsp.isZero, $rhsp}", "replaceWRhs(nodep)");
7364 #line 7365 "V3Const__gen.cpp"
7365 #line 3500 "../V3Const.cpp"
7366 // TREEOP ("AstShiftL {$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)");
7367 #line 7368 "V3Const__gen.cpp"
7368 #line 3501 "../V3Const.cpp"
7369 // TREEOP ("AstShiftLOvr {$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)");
7370 #line 7371 "V3Const__gen.cpp"
7371 #line 3502 "../V3Const.cpp"
7372 // TREEOP ("AstShiftR {$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)");
7373 #line 7374 "V3Const__gen.cpp"
7374 #line 3503 "../V3Const.cpp"
7375 // TREEOP ("AstShiftROvr {$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)");
7376 #line 7377 "V3Const__gen.cpp"
7377 #line 3504 "../V3Const.cpp"
7378 // TREEOP ("AstShiftRS {$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)");
7379 #line 7380 "V3Const__gen.cpp"
7380 #line 3505 "../V3Const.cpp"
7381 // TREEOP ("AstShiftRSOvr{$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)");
7382 #line 7383 "V3Const__gen.cpp"
7383 #line 3506 "../V3Const.cpp"
7384 // TREEOP ("AstXor {$lhsp.isZero, $rhsp}", "replaceWRhs(nodep)");
7385 #line 7386 "V3Const__gen.cpp"
7386 #line 3507 "../V3Const.cpp"
7387 // TREEOP ("AstSub {$lhsp.isZero, $rhsp}", "AstNegate{$rhsp}");
7388 #line 7389 "V3Const__gen.cpp"
7389 #line 3508 "../V3Const.cpp"
7390 // TREEOP ("AstAdd {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
7391 #line 7392 "V3Const__gen.cpp"
7392 #line 3509 "../V3Const.cpp"
7393 // TREEOP ("AstAnd {$lhsp, $rhsp.isZero}", "replaceZeroChkPure(nodep,$lhsp)");
7394 #line 7395 "V3Const__gen.cpp"
7395 #line 3510 "../V3Const.cpp"
7396 // TREEOP ("AstLogAnd{$lhsp, $rhsp.isZero}", "replaceZeroChkPure(nodep,$lhsp)");
7397 #line 7398 "V3Const__gen.cpp"
7398 #line 3511 "../V3Const.cpp"
7399 // TREEOP ("AstLogOr {$lhsp, $rhsp.isZero}", "replaceWLhsBool(nodep)");
7400 #line 7401 "V3Const__gen.cpp"
7401 #line 3512 "../V3Const.cpp"
7402 // TREEOP ("AstMul {$lhsp, $rhsp.isZero}", "replaceZeroChkPure(nodep,$lhsp)");
7403 #line 7404 "V3Const__gen.cpp"
7404 #line 3513 "../V3Const.cpp"
7405 // TREEOP ("AstMulS {$lhsp, $rhsp.isZero}", "replaceZeroChkPure(nodep,$lhsp)");
7406 #line 7407 "V3Const__gen.cpp"
7407 #line 3514 "../V3Const.cpp"
7408 // TREEOP ("AstOr {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
7409 #line 7410 "V3Const__gen.cpp"
7410 #line 3515 "../V3Const.cpp"
7411 // TREEOP ("AstShiftL {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
7412 #line 7413 "V3Const__gen.cpp"
7413 #line 3516 "../V3Const.cpp"
7414 // TREEOP ("AstShiftLOvr {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
7415 #line 7416 "V3Const__gen.cpp"
7416 #line 3517 "../V3Const.cpp"
7417 // TREEOP ("AstShiftR {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
7418 #line 7419 "V3Const__gen.cpp"
7419 #line 3518 "../V3Const.cpp"
7420 // TREEOP ("AstShiftROvr {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
7421 #line 7422 "V3Const__gen.cpp"
7422 #line 3519 "../V3Const.cpp"
7423 // TREEOP ("AstShiftRS {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
7424 #line 7425 "V3Const__gen.cpp"
7425 #line 3520 "../V3Const.cpp"
7426 // TREEOP ("AstShiftRSOvr{$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
7427 #line 7428 "V3Const__gen.cpp"
7428 #line 3521 "../V3Const.cpp"
7429 // TREEOP ("AstSub {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
7430 #line 7431 "V3Const__gen.cpp"
7431 #line 3522 "../V3Const.cpp"
7432 // TREEOP ("AstXor {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
7433 #line 7434 "V3Const__gen.cpp"
7434 #line 3523 "../V3Const.cpp"
7435 // Non-zero on one side or the other
7436 // TREEOP ("AstAnd {$lhsp.isAllOnes, $rhsp}", "replaceWRhs(nodep)");
7437 #line 7438 "V3Const__gen.cpp"
7438 #line 3525 "../V3Const.cpp"
7439 // TREEOP ("AstLogAnd{$lhsp.isNeqZero, $rhsp}", "replaceWRhsBool(nodep)");
7440 #line 7441 "V3Const__gen.cpp"
7441 #line 3526 "../V3Const.cpp"
7442 // TREEOP ("AstOr {$lhsp.isAllOnes, $rhsp, $rhsp.isPure}", "replaceWLhs(nodep)"); // ->allOnes
7443 #line 7444 "V3Const__gen.cpp"
7444 #line 3527 "../V3Const.cpp"
7445 // TREEOP ("AstLogOr {$lhsp.isNeqZero, $rhsp}", "replaceNum(nodep,1)");
7446 #line 7447 "V3Const__gen.cpp"
7447 #line 3528 "../V3Const.cpp"
7448 // TREEOP ("AstAnd {$lhsp, $rhsp.isAllOnes}", "replaceWLhs(nodep)");
7449 #line 7450 "V3Const__gen.cpp"
7450 #line 3529 "../V3Const.cpp"
7451 // TREEOP ("AstLogAnd{$lhsp, $rhsp.isNeqZero}", "replaceWLhsBool(nodep)");
7452 #line 7453 "V3Const__gen.cpp"
7453 #line 3530 "../V3Const.cpp"
7454 // TREEOP ("AstOr {$lhsp, $rhsp.isAllOnes, $lhsp.isPure}", "replaceWRhs(nodep)"); // ->allOnes
7455 #line 7456 "V3Const__gen.cpp"
7456 #line 3531 "../V3Const.cpp"
7457 // TREEOP ("AstLogOr {$lhsp, $rhsp.isNeqZero, $lhsp.isPure, nodep->isPure()}", "replaceNum(nodep,1)");
7458 #line 7459 "V3Const__gen.cpp"
7459 #line 3532 "../V3Const.cpp"
7460 // TREEOP ("AstXor {$lhsp.isAllOnes, $rhsp}", "AstNot{$rhsp}");
7461 #line 7462 "V3Const__gen.cpp"
7462 #line 3533 "../V3Const.cpp"
7463 // TREEOP ("AstMul {$lhsp.isOne, $rhsp}", "replaceWRhs(nodep)");
7464 #line 7465 "V3Const__gen.cpp"
7465 #line 3534 "../V3Const.cpp"
7466 // TREEOP ("AstMulS {$lhsp.isOne, $rhsp}", "replaceWRhs(nodep)");
7467 #line 7468 "V3Const__gen.cpp"
7468 #line 3535 "../V3Const.cpp"
7469 // TREEOP ("AstDiv {$lhsp, $rhsp.isOne}", "replaceWLhs(nodep)");
7470 #line 7471 "V3Const__gen.cpp"
7471 #line 3536 "../V3Const.cpp"
7472 // TREEOP ("AstDivS {$lhsp, $rhsp.isOne}", "replaceWLhs(nodep)");
7473 #line 7474 "V3Const__gen.cpp"
7474 #line 3537 "../V3Const.cpp"
7475 // TREEOP ("AstMul {operandIsPowTwo($lhsp), operandsSameWidth($lhsp,,$rhsp)}", "replaceMulShift(nodep)"); // a*2^n -> a<<n
7476 #line 7477 "V3Const__gen.cpp"
7477 #line 3538 "../V3Const.cpp"
7478 // TREEOP ("AstDiv {$lhsp, operandIsPowTwo($rhsp)}", "replaceDivShift(nodep)"); // a/2^n -> a>>n
7479 #line 7480 "V3Const__gen.cpp"
7480 #line 3539 "../V3Const.cpp"
7481 // TREEOP ("AstModDiv{$lhsp, operandIsPowTwo($rhsp)}", "replaceModAnd(nodep)"); // a % 2^n -> a&(2^n-1)
7482 #line 7483 "V3Const__gen.cpp"
7483 #line 3540 "../V3Const.cpp"
7484 // TREEOP ("AstPow {operandIsTwo($lhsp), !$rhsp.isZero}", "replacePowShift(nodep)"); // 2**a == 1<<a
7485 #line 7486 "V3Const__gen.cpp"
7486 #line 3541 "../V3Const.cpp"
7487 // TREEOP ("AstSub {$lhsp.castAdd, operandSubAdd(nodep)}", "AstAdd{AstSub{$lhsp->castAdd()->lhsp(),$rhsp}, $lhsp->castAdd()->rhsp()}"); // ((a+x)-y) -> (a+(x-y))
7488 #line 7489 "V3Const__gen.cpp"
7489 #line 3542 "../V3Const.cpp"
7490 // TREEOPC("AstAnd {$lhsp.isOne, matchRedundantClean(nodep)}", "DONE") // 1 & (a == b) -> (IData)(a == b)
7491 #line 7492 "V3Const__gen.cpp"
7492 #line 3543 "../V3Const.cpp"
7493 // Trinary ops
7494 // Note V3Case::Sel requires Cond to always be conditionally executed in C to prevent core dump!
7495 // TREEOP ("AstNodeCond{$condp.isZero, $thenp, $elsep}", "replaceWChild(nodep,$elsep)");
7496 #line 7497 "V3Const__gen.cpp"
7497 #line 3546 "../V3Const.cpp"
7498 // TREEOP ("AstNodeCond{$condp.isNeqZero, $thenp, $elsep}", "replaceWChild(nodep,$thenp)");
7499 #line 7500 "V3Const__gen.cpp"
7500 #line 3547 "../V3Const.cpp"
7501 // TREEOPA("AstNodeCond{$condp.isZero, $thenp.castConst, $elsep.castConst}", "replaceWChild(nodep,$elsep)");
7502 #line 7503 "V3Const__gen.cpp"
7503 #line 3548 "../V3Const.cpp"
7504 // TREEOPA("AstNodeCond{$condp.isNeqZero, $thenp.castConst, $elsep.castConst}", "replaceWChild(nodep,$thenp)");
7505 #line 7506 "V3Const__gen.cpp"
7506 #line 3549 "../V3Const.cpp"
7507 // TREEOP ("AstNodeCond{$condp, operandsSame($thenp,,$elsep)}","replaceWChild(nodep,$thenp)");
7508 #line 7509 "V3Const__gen.cpp"
7509 #line 3550 "../V3Const.cpp"
7510 // This visit function here must allow for short-circuiting.
7511 // TREEOPS("AstCond {$condp.isZero}", "replaceWIteratedThs(nodep)");
7512 #line 7513 "V3Const__gen.cpp"
7513 #line 3552 "../V3Const.cpp"
7514 // TREEOPS("AstCond {$condp.isNeqZero}", "replaceWIteratedRhs(nodep)");
7515 #line 7516 "V3Const__gen.cpp"
7516 #line 3553 "../V3Const.cpp"
7517 // TREEOP ("AstCond{$condp.castNot, $thenp, $elsep}", "AstCond{$condp->castNot()->lhsp(), $elsep, $thenp}");
7518 #line 7519 "V3Const__gen.cpp"
7519 #line 3554 "../V3Const.cpp"
7520 // TREEOP ("AstNodeCond{$condp.width1, $thenp.width1, $thenp.isAllOnes, $elsep}", "AstLogOr {$condp, $elsep}"); // a?1:b == a||b
7521 #line 7522 "V3Const__gen.cpp"
7522 #line 3555 "../V3Const.cpp"
7523 // TREEOP ("AstNodeCond{$condp.width1, $thenp.width1, $thenp, $elsep.isZero, !$elsep.isClassHandleValue}", "AstLogAnd{$condp, $thenp}"); // a?b:0 == a&&b
7524 #line 7525 "V3Const__gen.cpp"
7525 #line 3556 "../V3Const.cpp"
7526 // TREEOP ("AstNodeCond{$condp.width1, $thenp.width1, $thenp, $elsep.isAllOnes}", "AstLogOr {AstNot{$condp}, $thenp}"); // a?b:1 == ~a||b
7527 #line 7528 "V3Const__gen.cpp"
7528 #line 3557 "../V3Const.cpp"
7529 // TREEOP ("AstNodeCond{$condp.width1, $thenp.width1, $thenp.isZero, !$thenp.isClassHandleValue, $elsep}", "AstLogAnd{AstNot{$condp}, $elsep}"); // a?0:b == ~a&&b
7530 #line 7531 "V3Const__gen.cpp"
7531 #line 3558 "../V3Const.cpp"
7532 // TREEOP ("AstNodeCond{!$condp.width1, operandBoolShift(nodep->condp())}", "replaceBoolShift(nodep->condp())");
7533 #line 7534 "V3Const__gen.cpp"
7534 #line 3559 "../V3Const.cpp"
7535 // Prefer constants on left, since that often needs a shift, it lets
7536 // constant red remove the shift
7537 // TREEOP ("AstNodeBiCom{!$lhsp.castConst, $rhsp.castConst}", "swapSides(nodep)");
7538 #line 7539 "V3Const__gen.cpp"
7539 #line 3562 "../V3Const.cpp"
7540 // TREEOP ("AstNodeBiComAsv{operandAsvConst(nodep)}", "replaceAsv(nodep)");
7541 #line 7542 "V3Const__gen.cpp"
7542 #line 3563 "../V3Const.cpp"
7543 // TREEOP ("AstNodeBiComAsv{operandAsvSame(nodep)}", "replaceAsv(nodep)");
7544 #line 7545 "V3Const__gen.cpp"
7545 #line 3564 "../V3Const.cpp"
7546 // TREEOP ("AstNodeBiComAsv{operandAsvLUp(nodep)}", "replaceAsvLUp(nodep)");
7547 #line 7548 "V3Const__gen.cpp"
7548 #line 3565 "../V3Const.cpp"
7549 // TREEOP ("AstNodeBiComAsv{operandAsvRUp(nodep)}", "replaceAsvRUp(nodep)");
7550 #line 7551 "V3Const__gen.cpp"
7551 #line 3566 "../V3Const.cpp"
7552 // TREEOP ("AstLt {!$lhsp.castConst,$rhsp.castConst}", "AstGt {$rhsp,$lhsp}");
7553 #line 7554 "V3Const__gen.cpp"
7554 #line 3567 "../V3Const.cpp"
7555 // TREEOP ("AstLtS {!$lhsp.castConst,$rhsp.castConst}", "AstGtS {$rhsp,$lhsp}");
7556 #line 7557 "V3Const__gen.cpp"
7557 #line 3568 "../V3Const.cpp"
7558 // TREEOP ("AstLte {!$lhsp.castConst,$rhsp.castConst}", "AstGte {$rhsp,$lhsp}");
7559 #line 7560 "V3Const__gen.cpp"
7560 #line 3569 "../V3Const.cpp"
7561 // TREEOP ("AstLteS {!$lhsp.castConst,$rhsp.castConst}", "AstGteS{$rhsp,$lhsp}");
7562 #line 7563 "V3Const__gen.cpp"
7563 #line 3570 "../V3Const.cpp"
7564 // TREEOP ("AstGt {!$lhsp.castConst,$rhsp.castConst}", "AstLt {$rhsp,$lhsp}");
7565 #line 7566 "V3Const__gen.cpp"
7566 #line 3571 "../V3Const.cpp"
7567 // TREEOP ("AstGtS {!$lhsp.castConst,$rhsp.castConst}", "AstLtS {$rhsp,$lhsp}");
7568 #line 7569 "V3Const__gen.cpp"
7569 #line 3572 "../V3Const.cpp"
7570 // TREEOP ("AstGte {!$lhsp.castConst,$rhsp.castConst}", "AstLte {$rhsp,$lhsp}");
7571 #line 7572 "V3Const__gen.cpp"
7572 #line 3573 "../V3Const.cpp"
7573 // TREEOP ("AstGteS {!$lhsp.castConst,$rhsp.castConst}", "AstLteS{$rhsp,$lhsp}");
7574 #line 7575 "V3Const__gen.cpp"
7575 #line 3574 "../V3Const.cpp"
7576 // v--- *1* as These ops are always first, as we warn before replacing
7577 // TREEOP1("AstLt {$lhsp, $rhsp.isZero}", "replaceNumSigned(nodep,0)");
7578 #line 7579 "V3Const__gen.cpp"
7579 #line 3576 "../V3Const.cpp"
7580 // TREEOP1("AstGte {$lhsp, $rhsp.isZero}", "replaceNumSigned(nodep,1)");
7581 #line 7582 "V3Const__gen.cpp"
7582 #line 3577 "../V3Const.cpp"
7583 // TREEOP1("AstGt {$lhsp.isZero, $rhsp}", "replaceNumSigned(nodep,0)");
7584 #line 7585 "V3Const__gen.cpp"
7585 #line 3578 "../V3Const.cpp"
7586 // TREEOP1("AstLte {$lhsp.isZero, $rhsp}", "replaceNumSigned(nodep,1)");
7587 #line 7588 "V3Const__gen.cpp"
7588 #line 3579 "../V3Const.cpp"
7589 // TREEOP1("AstGt {$lhsp, $rhsp.isAllOnes, $lhsp->width()==$rhsp->width()}", "replaceNumLimited(nodep,0)");
7590 #line 7591 "V3Const__gen.cpp"
7591 #line 3580 "../V3Const.cpp"
7592 // TREEOP1("AstLte {$lhsp, $rhsp.isAllOnes, $lhsp->width()==$rhsp->width()}", "replaceNumLimited(nodep,1)");
7593 #line 7594 "V3Const__gen.cpp"
7594 #line 3581 "../V3Const.cpp"
7595 // TREEOP1("AstLt {$lhsp.isAllOnes, $rhsp, $lhsp->width()==$rhsp->width()}", "replaceNumLimited(nodep,0)");
7596 #line 7597 "V3Const__gen.cpp"
7597 #line 3582 "../V3Const.cpp"
7598 // TREEOP1("AstGte {$lhsp.isAllOnes, $rhsp, $lhsp->width()==$rhsp->width()}", "replaceNumLimited(nodep,1)");
7599 #line 7600 "V3Const__gen.cpp"
7600 #line 3583 "../V3Const.cpp"
7601 // Two level bubble pushing
7602 // TREEOP ("AstNot {$lhsp.castNot, $lhsp->width()==VN_AS($lhsp,,Not)->lhsp()->width()}", "replaceWChild(nodep, $lhsp->castNot()->lhsp())"); // NOT(NOT(x))->x
7603 #line 7604 "V3Const__gen.cpp"
7604 #line 3585 "../V3Const.cpp"
7605 // TREEOP ("AstLogNot{$lhsp.castLogNot}", "replaceWChild(nodep, $lhsp->castLogNot()->lhsp())"); // LOGNOT(LOGNOT(x))->x
7606 #line 7607 "V3Const__gen.cpp"
7607 #line 3586 "../V3Const.cpp"
7608 // TREEOPV("AstNot {$lhsp.castEqCase, $lhsp.width1}","AstNeqCase{$lhsp->castEqCase()->lhsp(),$lhsp->castEqCase()->rhsp()}");
7609 #line 7610 "V3Const__gen.cpp"
7610 #line 3587 "../V3Const.cpp"
7611 // TREEOP ("AstLogNot{$lhsp.castEqCase}", "AstNeqCase{$lhsp->castEqCase()->lhsp(),$lhsp->castEqCase()->rhsp()}");
7612 #line 7613 "V3Const__gen.cpp"
7613 #line 3588 "../V3Const.cpp"
7614 // TREEOPV("AstNot {$lhsp.castNeqCase, $lhsp.width1}","AstEqCase{$lhsp->castNeqCase()->lhsp(),$lhsp->castNeqCase()->rhsp()}");
7615 #line 7616 "V3Const__gen.cpp"
7616 #line 3589 "../V3Const.cpp"
7617 // TREEOP ("AstLogNot{$lhsp.castNeqCase}", "AstEqCase {$lhsp->castNeqCase()->lhsp(),$lhsp->castNeqCase()->rhsp()}");
7618 #line 7619 "V3Const__gen.cpp"
7619 #line 3590 "../V3Const.cpp"
7620 // TREEOPV("AstNot {$lhsp.castEqWild, $lhsp.width1}","AstNeqWild{$lhsp->castEqWild()->lhsp(),$lhsp->castEqWild()->rhsp()}");
7621 #line 7622 "V3Const__gen.cpp"
7622 #line 3591 "../V3Const.cpp"
7623 // TREEOP ("AstLogNot{$lhsp.castEqWild}", "AstNeqWild{$lhsp->castEqWild()->lhsp(),$lhsp->castEqWild()->rhsp()}");
7624 #line 7625 "V3Const__gen.cpp"
7625 #line 3592 "../V3Const.cpp"
7626 // TREEOPV("AstNot {$lhsp.castNeqWild, $lhsp.width1}","AstEqWild{$lhsp->castNeqWild()->lhsp(),$lhsp->castNeqWild()->rhsp()}");
7627 #line 7628 "V3Const__gen.cpp"
7628 #line 3593 "../V3Const.cpp"
7629 // TREEOP ("AstLogNot{$lhsp.castNeqWild}", "AstEqWild {$lhsp->castNeqWild()->lhsp(),$lhsp->castNeqWild()->rhsp()}");
7630 #line 7631 "V3Const__gen.cpp"
7631 #line 3594 "../V3Const.cpp"
7632 // TREEOPV("AstNot {$lhsp.castEq, $lhsp.width1}", "AstNeq {$lhsp->castEq()->lhsp(),$lhsp->castEq()->rhsp()}");
7633 #line 7634 "V3Const__gen.cpp"
7634 #line 3595 "../V3Const.cpp"
7635 // TREEOP ("AstLogNot{$lhsp.castEq}", "AstNeq {$lhsp->castEq()->lhsp(),$lhsp->castEq()->rhsp()}");
7636 #line 7637 "V3Const__gen.cpp"
7637 #line 3596 "../V3Const.cpp"
7638 // TREEOPV("AstNot {$lhsp.castNeq, $lhsp.width1}", "AstEq {$lhsp->castNeq()->lhsp(),$lhsp->castNeq()->rhsp()}");
7639 #line 7640 "V3Const__gen.cpp"
7640 #line 3597 "../V3Const.cpp"
7641 // TREEOP ("AstLogNot{$lhsp.castNeq}", "AstEq {$lhsp->castNeq()->lhsp(),$lhsp->castNeq()->rhsp()}");
7642 #line 7643 "V3Const__gen.cpp"
7643 #line 3598 "../V3Const.cpp"
7644 // TREEOPV("AstNot {$lhsp.castLt, $lhsp.width1}", "AstGte {$lhsp->castLt()->lhsp(),$lhsp->castLt()->rhsp()}");
7645 #line 7646 "V3Const__gen.cpp"
7646 #line 3599 "../V3Const.cpp"
7647 // TREEOP ("AstLogNot{$lhsp.castLt}", "AstGte {$lhsp->castLt()->lhsp(),$lhsp->castLt()->rhsp()}");
7648 #line 7649 "V3Const__gen.cpp"
7649 #line 3600 "../V3Const.cpp"
7650 // TREEOPV("AstNot {$lhsp.castLtS, $lhsp.width1}", "AstGteS{$lhsp->castLtS()->lhsp(),$lhsp->castLtS()->rhsp()}");
7651 #line 7652 "V3Const__gen.cpp"
7652 #line 3601 "../V3Const.cpp"
7653 // TREEOP ("AstLogNot{$lhsp.castLtS}", "AstGteS{$lhsp->castLtS()->lhsp(),$lhsp->castLtS()->rhsp()}");
7654 #line 7655 "V3Const__gen.cpp"
7655 #line 3602 "../V3Const.cpp"
7656 // TREEOPV("AstNot {$lhsp.castLte, $lhsp.width1}", "AstGt {$lhsp->castLte()->lhsp(),$lhsp->castLte()->rhsp()}");
7657 #line 7658 "V3Const__gen.cpp"
7658 #line 3603 "../V3Const.cpp"
7659 // TREEOP ("AstLogNot{$lhsp.castLte}", "AstGt {$lhsp->castLte()->lhsp(),$lhsp->castLte()->rhsp()}");
7660 #line 7661 "V3Const__gen.cpp"
7661 #line 3604 "../V3Const.cpp"
7662 // TREEOPV("AstNot {$lhsp.castLteS, $lhsp.width1}", "AstGtS {$lhsp->castLteS()->lhsp(),$lhsp->castLteS()->rhsp()}");
7663 #line 7664 "V3Const__gen.cpp"
7664 #line 3605 "../V3Const.cpp"
7665 // TREEOP ("AstLogNot{$lhsp.castLteS}", "AstGtS {$lhsp->castLteS()->lhsp(),$lhsp->castLteS()->rhsp()}");
7666 #line 7667 "V3Const__gen.cpp"
7667 #line 3606 "../V3Const.cpp"
7668 // TREEOPV("AstNot {$lhsp.castGt, $lhsp.width1}", "AstLte {$lhsp->castGt()->lhsp(),$lhsp->castGt()->rhsp()}");
7669 #line 7670 "V3Const__gen.cpp"
7670 #line 3607 "../V3Const.cpp"
7671 // TREEOP ("AstLogNot{$lhsp.castGt}", "AstLte {$lhsp->castGt()->lhsp(),$lhsp->castGt()->rhsp()}");
7672 #line 7673 "V3Const__gen.cpp"
7673 #line 3608 "../V3Const.cpp"
7674 // TREEOPV("AstNot {$lhsp.castGtS, $lhsp.width1}", "AstLteS{$lhsp->castGtS()->lhsp(),$lhsp->castGtS()->rhsp()}");
7675 #line 7676 "V3Const__gen.cpp"
7676 #line 3609 "../V3Const.cpp"
7677 // TREEOP ("AstLogNot{$lhsp.castGtS}", "AstLteS{$lhsp->castGtS()->lhsp(),$lhsp->castGtS()->rhsp()}");
7678 #line 7679 "V3Const__gen.cpp"
7679 #line 3610 "../V3Const.cpp"
7680 // TREEOPV("AstNot {$lhsp.castGte, $lhsp.width1}", "AstLt {$lhsp->castGte()->lhsp(),$lhsp->castGte()->rhsp()}");
7681 #line 7682 "V3Const__gen.cpp"
7682 #line 3611 "../V3Const.cpp"
7683 // TREEOP ("AstLogNot{$lhsp.castGte}", "AstLt {$lhsp->castGte()->lhsp(),$lhsp->castGte()->rhsp()}");
7684 #line 7685 "V3Const__gen.cpp"
7685 #line 3612 "../V3Const.cpp"
7686 // TREEOPV("AstNot {$lhsp.castGteS, $lhsp.width1}", "AstLtS {$lhsp->castGteS()->lhsp(),$lhsp->castGteS()->rhsp()}");
7687 #line 7688 "V3Const__gen.cpp"
7688 #line 3613 "../V3Const.cpp"
7689 // TREEOP ("AstLogNot{$lhsp.castGteS}", "AstLtS {$lhsp->castGteS()->lhsp(),$lhsp->castGteS()->rhsp()}");
7690 #line 7691 "V3Const__gen.cpp"
7691 #line 3614 "../V3Const.cpp"
7692 // Not common, but avoids compiler warnings about over shifting
7693 // TREEOP ("AstShiftL {operandHugeShiftL(nodep)}", "replaceZero(nodep)");
7694 #line 7695 "V3Const__gen.cpp"
7695 #line 3616 "../V3Const.cpp"
7696 // TREEOP ("AstShiftLOvr{operandHugeShiftL(nodep)}", "replaceZero(nodep)");
7697 #line 7698 "V3Const__gen.cpp"
7698 #line 3617 "../V3Const.cpp"
7699 // TREEOP ("AstShiftR {operandHugeShiftR(nodep)}", "replaceZero(nodep)");
7700 #line 7701 "V3Const__gen.cpp"
7701 #line 3618 "../V3Const.cpp"
7702 // TREEOP ("AstShiftROvr{operandHugeShiftR(nodep)}", "replaceZero(nodep)");
7703 #line 7704 "V3Const__gen.cpp"
7704 #line 3619 "../V3Const.cpp"
7705 // TREEOP ("AstShiftL{operandShiftOp(nodep)}", "replaceShiftOp(nodep)");
7706 #line 7707 "V3Const__gen.cpp"
7707 #line 3620 "../V3Const.cpp"
7708 // TREEOP ("AstShiftR{operandShiftOp(nodep)}", "replaceShiftOp(nodep)");
7709 #line 7710 "V3Const__gen.cpp"
7710 #line 3621 "../V3Const.cpp"
7711 // TREEOP ("AstShiftL{operandShiftShift(nodep)}", "replaceShiftShift(nodep)");
7712 #line 7713 "V3Const__gen.cpp"
7713 #line 3622 "../V3Const.cpp"
7714 // TREEOP ("AstShiftR{operandShiftShift(nodep)}", "replaceShiftShift(nodep)");
7715 #line 7716 "V3Const__gen.cpp"
7716 #line 3623 "../V3Const.cpp"
7717 // TREEOP ("AstWordSel{operandWordOOB(nodep)}", "replaceZero(nodep)");
7718 #line 7719 "V3Const__gen.cpp"
7719 #line 3624 "../V3Const.cpp"
7720 // Compress out EXTENDs to appease loop unroller
7721 // TREEOPV("AstEq {$rhsp.castExtend,operandBiExtendConstShrink(nodep)}", "DONE");
7722 #line 7723 "V3Const__gen.cpp"
7723 #line 3626 "../V3Const.cpp"
7724 // TREEOPV("AstNeq {$rhsp.castExtend,operandBiExtendConstShrink(nodep)}", "DONE");
7725 #line 7726 "V3Const__gen.cpp"
7726 #line 3627 "../V3Const.cpp"
7727 // TREEOPV("AstGt {$rhsp.castExtend,operandBiExtendConstShrink(nodep)}", "DONE");
7728 #line 7729 "V3Const__gen.cpp"
7729 #line 3628 "../V3Const.cpp"
7730 // TREEOPV("AstGte {$rhsp.castExtend,operandBiExtendConstShrink(nodep)}", "DONE");
7731 #line 7732 "V3Const__gen.cpp"
7732 #line 3629 "../V3Const.cpp"
7733 // TREEOPV("AstLt {$rhsp.castExtend,operandBiExtendConstShrink(nodep)}", "DONE");
7734 #line 7735 "V3Const__gen.cpp"
7735 #line 3630 "../V3Const.cpp"
7736 // TREEOPV("AstLte {$rhsp.castExtend,operandBiExtendConstShrink(nodep)}", "DONE");
7737 #line 7738 "V3Const__gen.cpp"
7738 #line 3631 "../V3Const.cpp"
7739 // TREEOPV("AstEq {$rhsp.castExtend,operandBiExtendConstOver(nodep)}", "replaceZero(nodep)");
7740 #line 7741 "V3Const__gen.cpp"
7741 #line 3632 "../V3Const.cpp"
7742 // TREEOPV("AstNeq {$rhsp.castExtend,operandBiExtendConstOver(nodep)}", "replaceNum(nodep,1)");
7743 #line 7744 "V3Const__gen.cpp"
7744 #line 3633 "../V3Const.cpp"
7745 // TREEOPV("AstGt {$rhsp.castExtend,operandBiExtendConstOver(nodep)}", "replaceNum(nodep,1)");
7746 #line 7747 "V3Const__gen.cpp"
7747 #line 3634 "../V3Const.cpp"
7748 // TREEOPV("AstGte {$rhsp.castExtend,operandBiExtendConstOver(nodep)}", "replaceNum(nodep,1)");
7749 #line 7750 "V3Const__gen.cpp"
7750 #line 3635 "../V3Const.cpp"
7751 // TREEOPV("AstLt {$rhsp.castExtend,operandBiExtendConstOver(nodep)}", "replaceZero(nodep)");
7752 #line 7753 "V3Const__gen.cpp"
7753 #line 3636 "../V3Const.cpp"
7754 // TREEOPV("AstLte {$rhsp.castExtend,operandBiExtendConstOver(nodep)}", "replaceZero(nodep)");
7755 #line 7756 "V3Const__gen.cpp"
7756 #line 3637 "../V3Const.cpp"
7757 // Identical operands on both sides
7758 // AstLogAnd/AstLogOr already converted to AstAnd/AstOr for these rules
7759 // AstAdd->ShiftL(#,1) but uncommon
7760 // TREEOP ("AstAnd {operandsSame($lhsp,,$rhsp)}", "replaceWLhs(nodep)");
7761 #line 7762 "V3Const__gen.cpp"
7762 #line 3641 "../V3Const.cpp"
7763 // TREEOP ("AstDiv {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
7764 #line 7765 "V3Const__gen.cpp"
7765 #line 3642 "../V3Const.cpp"
7766 // TREEOP ("AstDivS {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
7767 #line 7768 "V3Const__gen.cpp"
7768 #line 3643 "../V3Const.cpp"
7769 // TREEOP ("AstOr {operandsSame($lhsp,,$rhsp)}", "replaceWLhs(nodep)");
7770 #line 7771 "V3Const__gen.cpp"
7771 #line 3644 "../V3Const.cpp"
7772 // TREEOP ("AstSub {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
7773 #line 7774 "V3Const__gen.cpp"
7774 #line 3645 "../V3Const.cpp"
7775 // TREEOP ("AstXor {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
7776 #line 7777 "V3Const__gen.cpp"
7777 #line 3646 "../V3Const.cpp"
7778 // TREEOP ("AstEq {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); // We let X==X -> 1, although in a true 4-state sim it's X.
7779 #line 7780 "V3Const__gen.cpp"
7780 #line 3647 "../V3Const.cpp"
7781 // TREEOP ("AstEqD {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); // We let X==X -> 1, although in a true 4-state sim it's X.
7782 #line 7783 "V3Const__gen.cpp"
7783 #line 3648 "../V3Const.cpp"
7784 // TREEOP ("AstEqN {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); // We let X==X -> 1, although in a true 4-state sim it's X.
7785 #line 7786 "V3Const__gen.cpp"
7786 #line 3649 "../V3Const.cpp"
7787 // TREEOP ("AstEqCase {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
7788 #line 7789 "V3Const__gen.cpp"
7789 #line 3650 "../V3Const.cpp"
7790 // TREEOP ("AstEqWild {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
7791 #line 7792 "V3Const__gen.cpp"
7792 #line 3651 "../V3Const.cpp"
7793 // TREEOP ("AstGt {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
7794 #line 7795 "V3Const__gen.cpp"
7795 #line 3652 "../V3Const.cpp"
7796 // TREEOP ("AstGtD {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
7797 #line 7798 "V3Const__gen.cpp"
7798 #line 3653 "../V3Const.cpp"
7799 // TREEOP ("AstGtN {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
7800 #line 7801 "V3Const__gen.cpp"
7801 #line 3654 "../V3Const.cpp"
7802 // TREEOP ("AstGtS {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
7803 #line 7804 "V3Const__gen.cpp"
7804 #line 3655 "../V3Const.cpp"
7805 // TREEOP ("AstGte {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
7806 #line 7807 "V3Const__gen.cpp"
7807 #line 3656 "../V3Const.cpp"
7808 // TREEOP ("AstGteD {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
7809 #line 7810 "V3Const__gen.cpp"
7810 #line 3657 "../V3Const.cpp"
7811 // TREEOP ("AstGteN {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
7812 #line 7813 "V3Const__gen.cpp"
7813 #line 3658 "../V3Const.cpp"
7814 // TREEOP ("AstGteS {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
7815 #line 7816 "V3Const__gen.cpp"
7816 #line 3659 "../V3Const.cpp"
7817 // TREEOP ("AstLt {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
7818 #line 7819 "V3Const__gen.cpp"
7819 #line 3660 "../V3Const.cpp"
7820 // TREEOP ("AstLtD {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
7821 #line 7822 "V3Const__gen.cpp"
7822 #line 3661 "../V3Const.cpp"
7823 // TREEOP ("AstLtN {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
7824 #line 7825 "V3Const__gen.cpp"
7825 #line 3662 "../V3Const.cpp"
7826 // TREEOP ("AstLtS {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
7827 #line 7828 "V3Const__gen.cpp"
7828 #line 3663 "../V3Const.cpp"
7829 // TREEOP ("AstLte {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
7830 #line 7831 "V3Const__gen.cpp"
7831 #line 3664 "../V3Const.cpp"
7832 // TREEOP ("AstLteD {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
7833 #line 7834 "V3Const__gen.cpp"
7834 #line 3665 "../V3Const.cpp"
7835 // TREEOP ("AstLteN {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
7836 #line 7837 "V3Const__gen.cpp"
7837 #line 3666 "../V3Const.cpp"
7838 // TREEOP ("AstLteS {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
7839 #line 7840 "V3Const__gen.cpp"
7840 #line 3667 "../V3Const.cpp"
7841 // TREEOP ("AstNeq {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
7842 #line 7843 "V3Const__gen.cpp"
7843 #line 3668 "../V3Const.cpp"
7844 // TREEOP ("AstNeqD {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
7845 #line 7846 "V3Const__gen.cpp"
7846 #line 3669 "../V3Const.cpp"
7847 // TREEOP ("AstNeqN {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
7848 #line 7849 "V3Const__gen.cpp"
7849 #line 3670 "../V3Const.cpp"
7850 // TREEOP ("AstNeqCase{operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
7851 #line 7852 "V3Const__gen.cpp"
7852 #line 3671 "../V3Const.cpp"
7853 // TREEOP ("AstNeqWild{operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
7854 #line 7855 "V3Const__gen.cpp"
7855 #line 3672 "../V3Const.cpp"
7856 // TREEOP ("AstLogAnd {operandsSame($lhsp,,$rhsp)}", "replaceWLhsBool(nodep)");
7857 #line 7858 "V3Const__gen.cpp"
7858 #line 3673 "../V3Const.cpp"
7859 // TREEOP ("AstLogOr {operandsSame($lhsp,,$rhsp)}", "replaceWLhsBool(nodep)");
7860 #line 7861 "V3Const__gen.cpp"
7861 #line 3674 "../V3Const.cpp"
7862 ///=== Verilog operators
7863 // Comparison against 1'b0/1'b1; must be careful about widths.
7864 // These use Not, so must be Verilog only
7865 // TREEOPV("AstEq {$rhsp.width1, $lhsp.isZero, $rhsp}", "AstNot{$rhsp}");
7866 #line 7867 "V3Const__gen.cpp"
7867 #line 3678 "../V3Const.cpp"
7868 // TREEOPV("AstEq {$lhsp.width1, $lhsp, $rhsp.isZero}", "AstNot{$lhsp}");
7869 #line 7870 "V3Const__gen.cpp"
7870 #line 3679 "../V3Const.cpp"
7871 // TREEOPV("AstEq {$rhsp.width1, $lhsp.isAllOnes, $rhsp}", "replaceWRhs(nodep)");
7872 #line 7873 "V3Const__gen.cpp"
7873 #line 3680 "../V3Const.cpp"
7874 // TREEOPV("AstEq {$lhsp.width1, $lhsp, $rhsp.isAllOnes}", "replaceWLhs(nodep)");
7875 #line 7876 "V3Const__gen.cpp"
7876 #line 3681 "../V3Const.cpp"
7877 // TREEOPV("AstNeq {$rhsp.width1, $lhsp.isZero, $rhsp}", "replaceWRhs(nodep)");
7878 #line 7879 "V3Const__gen.cpp"
7879 #line 3682 "../V3Const.cpp"
7880 // TREEOPV("AstNeq {$lhsp.width1, $lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
7881 #line 7882 "V3Const__gen.cpp"
7882 #line 3683 "../V3Const.cpp"
7883 // TREEOPV("AstNeq {$rhsp.width1, $lhsp.isAllOnes, $rhsp}", "AstNot{$rhsp}");
7884 #line 7885 "V3Const__gen.cpp"
7885 #line 3684 "../V3Const.cpp"
7886 // TREEOPV("AstNeq {$lhsp.width1, $lhsp, $rhsp.isAllOnes}", "AstNot{$lhsp}");
7887 #line 7888 "V3Const__gen.cpp"
7888 #line 3685 "../V3Const.cpp"
7889 // TREEOPV("AstLt {$rhsp.width1, $lhsp.isZero, $rhsp}", "replaceWRhs(nodep)"); // Because not signed #s
7890 #line 7891 "V3Const__gen.cpp"
7891 #line 3686 "../V3Const.cpp"
7892 // TREEOPV("AstGt {$lhsp.width1, $lhsp, $rhsp.isZero}", "replaceWLhs(nodep)"); // Because not signed #s
7893 #line 7894 "V3Const__gen.cpp"
7894 #line 3687 "../V3Const.cpp"
7895 // Useful for CONDs added around ARRAYSEL's in V3Case step
7896 // TREEOPV("AstLte {$lhsp->width()==$rhsp->width(), $rhsp.isAllOnes}", "replaceNum(nodep,1)");
7897 #line 7898 "V3Const__gen.cpp"
7898 #line 3689 "../V3Const.cpp"
7899 // Simplify reduction operators
7900 // This also gets &{...,0,....} => const 0 (Common for unused_ok signals)
7901 // TREEOPV("AstRedAnd{$lhsp, $lhsp.width1}", "replaceWLhs(nodep)");
7902 #line 7903 "V3Const__gen.cpp"
7903 #line 3692 "../V3Const.cpp"
7904 // TREEOPV("AstRedOr {$lhsp, $lhsp.width1}", "replaceWLhs(nodep)");
7905 #line 7906 "V3Const__gen.cpp"
7906 #line 3693 "../V3Const.cpp"
7907 // TREEOPV("AstRedXor{$lhsp, $lhsp.width1}", "replaceWLhs(nodep)");
7908 #line 7909 "V3Const__gen.cpp"
7909 #line 3694 "../V3Const.cpp"
7910 // TREEOPV("AstRedAnd{$lhsp.castConcat}", "AstAnd{AstRedAnd{$lhsp->castConcat()->lhsp()}, AstRedAnd{$lhsp->castConcat()->rhsp()}}"); // &{a,b} => {&a}&{&b}
7911 #line 7912 "V3Const__gen.cpp"
7912 #line 3695 "../V3Const.cpp"
7913 // TREEOPV("AstRedOr {$lhsp.castConcat}", "AstOr {AstRedOr {$lhsp->castConcat()->lhsp()}, AstRedOr {$lhsp->castConcat()->rhsp()}}"); // |{a,b} => {|a}|{|b}
7914 #line 7915 "V3Const__gen.cpp"
7915 #line 3696 "../V3Const.cpp"
7916 // TREEOPV("AstRedXor{$lhsp.castConcat}", "AstXor{AstRedXor{$lhsp->castConcat()->lhsp()}, AstRedXor{$lhsp->castConcat()->rhsp()}}"); // ^{a,b} => {^a}^{^b}
7917 #line 7918 "V3Const__gen.cpp"
7918 #line 3697 "../V3Const.cpp"
7919 // TREEOPV("AstRedAnd{$lhsp.castExtend, $lhsp->width() > VN_AS($lhsp,,Extend)->lhsp()->width()}", "replaceZero(nodep)"); // &{0,...} => 0 Prevents compiler limited range error
7920 #line 7921 "V3Const__gen.cpp"
7921 #line 3698 "../V3Const.cpp"
7922 // TREEOPV("AstRedOr {$lhsp.castExtend}", "AstRedOr {$lhsp->castExtend()->lhsp()}");
7923 #line 7924 "V3Const__gen.cpp"
7924 #line 3699 "../V3Const.cpp"
7925 // TREEOPV("AstRedXor{$lhsp.castExtend}", "AstRedXor{$lhsp->castExtend()->lhsp()}");
7926 #line 7927 "V3Const__gen.cpp"
7927 #line 3700 "../V3Const.cpp"
7928 // TREEOP ("AstRedXor{$lhsp.castXor, VN_IS(VN_AS($lhsp,,Xor)->lhsp(),,Const)}", "AstXor{AstRedXor{$lhsp->castXor()->lhsp()}, AstRedXor{$lhsp->castXor()->rhsp()}}"); // ^(const ^ a) => (^const)^(^a)
7929 #line 7930 "V3Const__gen.cpp"
7930 #line 3701 "../V3Const.cpp"
7931 // TREEOPC("AstAnd {$lhsp.castConst, $rhsp.castRedXor, matchBitOpTree(nodep)}", "DONE");
7932 #line 7933 "V3Const__gen.cpp"
7933 #line 3702 "../V3Const.cpp"
7934 // TREEOPV("AstOneHot{$lhsp.width1}", "replaceWLhs(nodep)");
7935 #line 7936 "V3Const__gen.cpp"
7936 #line 3703 "../V3Const.cpp"
7937 // TREEOPV("AstOneHot0{$lhsp.width1}", "replaceNum(nodep,1)");
7938 #line 7939 "V3Const__gen.cpp"
7939 #line 3704 "../V3Const.cpp"
7940 // Binary AND/OR is faster than logical and/or (usually)
7941 // TREEOPV("AstLogAnd{matchBiopToBitwise(nodep)}", "AstAnd{$lhsp,$rhsp}");
7942 #line 7943 "V3Const__gen.cpp"
7943 #line 3706 "../V3Const.cpp"
7944 // TREEOPV("AstLogOr {matchBiopToBitwise(nodep)}", "AstOr{$lhsp,$rhsp}");
7945 #line 7946 "V3Const__gen.cpp"
7946 #line 3707 "../V3Const.cpp"
7947 // TREEOPV("AstLogNot{$lhsp.width1}", "AstNot{$lhsp}");
7948 #line 7949 "V3Const__gen.cpp"
7949 #line 3708 "../V3Const.cpp"
7950 // CONCAT(CONCAT({a},{b}),{c}) -> CONCAT({a},CONCAT({b},{c}))
7951 // CONCAT({const},CONCAT({const},{c})) -> CONCAT((constifiedCONC{const|const},{c}))
7952 // TREEOPV("AstConcat{matchConcatRand(nodep)}", "DONE");
7953 #line 7954 "V3Const__gen.cpp"
7954 #line 3711 "../V3Const.cpp"
7955 // TREEOPV("AstConcat{operandConcatMove(nodep)}", "moveConcat(nodep)");
7956 #line 7957 "V3Const__gen.cpp"
7957 #line 3712 "../V3Const.cpp"
7958 // TREEOPV("AstConcat{$lhsp.isZero, $rhsp}", "replaceExtend(nodep, nodep->rhsp())");
7959 #line 7960 "V3Const__gen.cpp"
7960 #line 3713 "../V3Const.cpp"
7961 // CONCAT(a[1],a[0]) -> a[1:0]
7962 // TREEOPV("AstConcat{$lhsp.castSel, $rhsp.castSel, ifAdjacentSel(VN_AS($lhsp,,Sel),,VN_AS($rhsp,,Sel))}", "replaceConcatSel(nodep)");
7963 #line 7964 "V3Const__gen.cpp"
7964 #line 3715 "../V3Const.cpp"
7965 // TREEOPV("AstConcat{ifConcatMergeableBiop($lhsp), concatMergeable($lhsp,,$rhsp,,0)}", "replaceConcatMerge(nodep)");
7966 #line 7967 "V3Const__gen.cpp"
7967 #line 3716 "../V3Const.cpp"
7968 // Common two-level operations that can be simplified
7969 // TREEOP ("AstAnd {$lhsp.castConst,matchAndCond(nodep)}", "DONE");
7970 #line 7971 "V3Const__gen.cpp"
7971 #line 3718 "../V3Const.cpp"
7972 // TREEOP ("AstAnd {$lhsp.castConst, $rhsp.castOr, matchMaskedOr(nodep)}", "DONE");
7973 #line 7974 "V3Const__gen.cpp"
7974 #line 3719 "../V3Const.cpp"
7975 // TREEOPC("AstAnd {$lhsp.castConst, matchMaskedShift(nodep)}", "DONE");
7976 #line 7977 "V3Const__gen.cpp"
7977 #line 3720 "../V3Const.cpp"
7978 // TREEOP ("AstAnd {$lhsp.castOr, $rhsp.castOr, operandAndOrSame(nodep)}", "replaceAndOr(nodep)");
7979 #line 7980 "V3Const__gen.cpp"
7980 #line 3721 "../V3Const.cpp"
7981 // TREEOP ("AstOr {$lhsp.castAnd,$rhsp.castAnd,operandAndOrSame(nodep)}", "replaceAndOr(nodep)");
7982 #line 7983 "V3Const__gen.cpp"
7983 #line 3722 "../V3Const.cpp"
7984 // TREEOP ("AstOr {matchOrAndNot(nodep)}", "DONE");
7985 #line 7986 "V3Const__gen.cpp"
7986 #line 3723 "../V3Const.cpp"
7987 // TREEOP ("AstAnd {operandShiftSame(nodep)}", "replaceShiftSame(nodep)");
7988 #line 7989 "V3Const__gen.cpp"
7989 #line 3724 "../V3Const.cpp"
7990 // TREEOP ("AstOr {operandShiftSame(nodep)}", "replaceShiftSame(nodep)");
7991 #line 7992 "V3Const__gen.cpp"
7992 #line 3725 "../V3Const.cpp"
7993 // TREEOP ("AstXor {operandShiftSame(nodep)}", "replaceShiftSame(nodep)");
7994 #line 7995 "V3Const__gen.cpp"
7995 #line 3726 "../V3Const.cpp"
7996 // TREEOPC("AstAnd {matchBitOpTree(nodep)}", "DONE");
7997 #line 7998 "V3Const__gen.cpp"
7998 #line 3727 "../V3Const.cpp"
7999 // TREEOPC("AstOr {matchBitOpTree(nodep)}", "DONE");
8000 #line 8001 "V3Const__gen.cpp"
8001 #line 3728 "../V3Const.cpp"
8002 // TREEOPC("AstXor {matchBitOpTree(nodep)}", "DONE");
8003 #line 8004 "V3Const__gen.cpp"
8004 #line 3729 "../V3Const.cpp"
8005 // Note can't simplify a extend{extends}, extends{extend}, as the sign
8006 // bits end up in the wrong places
8007 // TREEOPV("AstExtend{operandsSameWidth(nodep,,$lhsp)}", "replaceWLhs(nodep)");
8008 #line 8009 "V3Const__gen.cpp"
8009 #line 3732 "../V3Const.cpp"
8010 // TREEOPV("AstExtend{$lhsp.castExtend}", "replaceExtend(nodep, VN_AS(nodep->lhsp(), Extend)->lhsp())");
8011 #line 8012 "V3Const__gen.cpp"
8012 #line 3733 "../V3Const.cpp"
8013 // TREEOPV("AstExtendS{$lhsp.castExtendS}", "replaceExtend(nodep, VN_AS(nodep->lhsp(), ExtendS)->lhsp())");
8014 #line 8015 "V3Const__gen.cpp"
8015 #line 3734 "../V3Const.cpp"
8016 // TREEOPV("AstReplicate{$srcp, $countp.isOne, $srcp->width()==nodep->width()}", "replaceWLhs(nodep)"); // {1{lhs}}->lhs
8017 #line 8018 "V3Const__gen.cpp"
8018 #line 3735 "../V3Const.cpp"
8019 // TREEOPV("AstReplicateN{$lhsp, $rhsp.isOne, $lhsp->width()==nodep->width()}", "replaceWLhs(nodep)"); // {1{lhs}}->lhs
8020 #line 8021 "V3Const__gen.cpp"
8021 #line 3736 "../V3Const.cpp"
8022 // TREEOPV("AstReplicate{$srcp.castReplicate, operandRepRep(nodep)}", "DONE"); // {2{3{lhs}}}->{6{lhs}}
8023 #line 8024 "V3Const__gen.cpp"
8024 #line 3737 "../V3Const.cpp"
8025 // TREEOPV("AstConcat{operandConcatSame(nodep)}", "DONE"); // {a,a}->{2{a}}, {a,2{a}}->{3{a}, etc
8026 #line 8027 "V3Const__gen.cpp"
8027 #line 3738 "../V3Const.cpp"
8028 // Next rule because AUTOINST puts the width of bits in
8029 // to pins, even when the widths are exactly the same across the hierarchy.
8030 // TREEOPV("AstSel{matchSelRand(nodep)}", "DONE");
8031 #line 8032 "V3Const__gen.cpp"
8032 #line 3741 "../V3Const.cpp"
8033 // TREEOPV("AstSel{operandSelExtend(nodep)}", "DONE");
8034 #line 8035 "V3Const__gen.cpp"
8035 #line 3742 "../V3Const.cpp"
8036 // TREEOPV("AstSel{operandSelFull(nodep)}", "replaceWChild(nodep, nodep->fromp())");
8037 #line 8038 "V3Const__gen.cpp"
8038 #line 3743 "../V3Const.cpp"
8039 // TREEOPV("AstSel{$fromp.castSel}", "replaceSelSel(nodep)");
8040 #line 8041 "V3Const__gen.cpp"
8041 #line 3744 "../V3Const.cpp"
8042 // TREEOPV("AstSel{$fromp.castAdd, operandSelBiLower(nodep)}", "DONE");
8043 #line 8044 "V3Const__gen.cpp"
8044 #line 3745 "../V3Const.cpp"
8045 // TREEOPV("AstSel{$fromp.castAnd, operandSelBiLower(nodep)}", "DONE");
8046 #line 8047 "V3Const__gen.cpp"
8047 #line 3746 "../V3Const.cpp"
8048 // TREEOPV("AstSel{$fromp.castOr, operandSelBiLower(nodep)}", "DONE");
8049 #line 8050 "V3Const__gen.cpp"
8050 #line 3747 "../V3Const.cpp"
8051 // TREEOPV("AstSel{$fromp.castSub, operandSelBiLower(nodep)}", "DONE");
8052 #line 8053 "V3Const__gen.cpp"
8053 #line 3748 "../V3Const.cpp"
8054 // TREEOPV("AstSel{$fromp.castXor, operandSelBiLower(nodep)}", "DONE");
8055 #line 8056 "V3Const__gen.cpp"
8056 #line 3749 "../V3Const.cpp"
8057 // TREEOPV("AstSel{$fromp.castShiftR, operandSelShiftLower(nodep)}", "DONE");
8058 #line 8059 "V3Const__gen.cpp"
8059 #line 3750 "../V3Const.cpp"
8060 // TREEOPA("AstSel{$fromp.castConst, $lsbp.castConst, $widthp.castConst, }", "replaceConst(nodep)");
8061 #line 8062 "V3Const__gen.cpp"
8062 #line 3751 "../V3Const.cpp"
8063 // TREEOPV("AstSel{$fromp.castConcat, $lsbp.castConst, $widthp.castConst, }", "replaceSelConcat(nodep)");
8064 #line 8065 "V3Const__gen.cpp"
8065 #line 3752 "../V3Const.cpp"
8066 // TREEOPV("AstSel{$fromp.castReplicate, $lsbp.castConst, $widthp.castConst, operandSelReplicate(nodep) }", "DONE");
8067 #line 8068 "V3Const__gen.cpp"
8068 #line 3753 "../V3Const.cpp"
8069 // V3Tristate requires selects below BufIf1.
8070 // Also do additional operators that are bit-independent, but only definite
8071 // win if bit select is a constant (otherwise we may need to compute bit index several times)
8072 // TREEOPV("AstSel{$fromp.castBufIf1}", "replaceSelIntoBiop(nodep)");
8073 #line 8074 "V3Const__gen.cpp"
8074 #line 3757 "../V3Const.cpp"
8075 // TREEOPV("AstSel{$fromp.castNot}", "replaceSelIntoUniop(nodep)");
8076 #line 8077 "V3Const__gen.cpp"
8077 #line 3758 "../V3Const.cpp"
8078 // TREEOPV("AstSel{$fromp.castAnd,$lsbp.castConst}", "replaceSelIntoBiop(nodep)");
8079 #line 8080 "V3Const__gen.cpp"
8080 #line 3759 "../V3Const.cpp"
8081 // TREEOPV("AstSel{$fromp.castOr,$lsbp.castConst}", "replaceSelIntoBiop(nodep)");
8082 #line 8083 "V3Const__gen.cpp"
8083 #line 3760 "../V3Const.cpp"
8084 // TREEOPV("AstSel{$fromp.castXor,$lsbp.castConst}", "replaceSelIntoBiop(nodep)");
8085 #line 8086 "V3Const__gen.cpp"
8086 #line 3761 "../V3Const.cpp"
8087 // This visit function here must allow for short-circuiting.
8088 // TREEOPS("AstLogIf{$lhsp.isZero}", "replaceNum(nodep, 1)");
8089 #line 8090 "V3Const__gen.cpp"
8090 #line 3763 "../V3Const.cpp"
8091 // TREEOPV("AstLogIf{$lhsp, $rhsp}", "AstLogOr{AstLogNot{$lhsp},$rhsp}");
8092 #line 8093 "V3Const__gen.cpp"
8093 #line 3764 "../V3Const.cpp"
8094 // TREEOPV("AstLogEq{$lhsp, $rhsp}", "replaceLogEq(nodep)");
8095 #line 8096 "V3Const__gen.cpp"
8096 #line 3765 "../V3Const.cpp"
8097 // Strings
8098 // TREEOPA("AstPutcN{$lhsp.castConst, $rhsp.castConst, $thsp.castConst}", "replaceConst(nodep)");
8099 #line 8100 "V3Const__gen.cpp"
8100 #line 3767 "../V3Const.cpp"
8101 // TREEOPA("AstSubstrN{$lhsp.castConst, $rhsp.castConst, $thsp.castConst}", "replaceConst(nodep)");
8102 #line 8103 "V3Const__gen.cpp"
8103 #line 3768 "../V3Const.cpp"
8104 // TREEOPA("AstCvtPackString{$lhsp.castConst}", "replaceConstString(nodep, VN_AS(nodep->lhsp(), Const)->num().toString())");
8105 #line 8106 "V3Const__gen.cpp"
8106 #line 3769 "../V3Const.cpp"
8107 // Custom
8108 // Implied by AstIsUnbounded::numberOperate: V("AstIsUnbounded{$lhsp.castConst}", "replaceNum(nodep, 0)");
8109 // TREEOPV("AstIsUnbounded{$lhsp.castUnbounded}", "replaceNum(nodep, 1)");
8110 #line 8111 "V3Const__gen.cpp"
8111 #line 3772 "../V3Const.cpp"
8112 // clang-format on
8113
8114 // Possible futures:
8115 // (a?(b?y:x):y) -> (a&&!b)?x:y
8116 // (a?(b?x:y):y) -> (a&&b)?x:y
8117 // (a?x:(b?x:y)) -> (a||b)?x:y
8118 // (a?x:(b?y:x)) -> (a||!b)?x:y
8119
8120 // Note we can't convert EqCase/NeqCase to Eq/Neq here because that would break 3'b1x1==3'b101
8121
8122 //-----
8123 void visit(AstNode* nodep) override {
8124 // Default: Just iterate
8125 if (m_required) {
8126 if (VN_IS(nodep, NodeDType) || VN_IS(nodep, Range) || VN_IS(nodep, SliceSel)) {
8127 // Ignore dtypes for parameter type pins
8128 } else {
8129 nodep->v3error("Expecting expression to be constant, but can't convert a "
8130 << nodep->prettyTypeName() << " to constant.");
8131 }
8132 } else {
8133 if (nodep->isTimingControl()) m_hasJumpDelay = true;
8134 // Calculate the width of this operation
8135 if (m_params && !nodep->width()) nodep = V3Width::widthParamsEdit(nodep);
8136 iterateChildren(nodep);
8137 }
8138 }
8139
8140 public:
8141 // Processing Mode Enum
8142 enum ProcMode : uint8_t {
8143 PROC_PARAMS_NOWARN,
8144 PROC_PARAMS,
8145 PROC_GENERATE,
8146 PROC_LIVE,
8147 PROC_V_WARN,
8148 PROC_V_NOWARN,
8149 PROC_V_EXPENSIVE,
8150 PROC_CPP
8151 };
8152
8153 // CONSTRUCTORS
8154 ConstVisitor(ProcMode pmode, bool globalPass)
8155 : m_globalPass{globalPass}
8156 , m_concswapNames{globalPass ? ("__Vconcswap_" + cvtToStr(s_globalPassNum++)) : ""} {
8157 // clang-format off
8158 switch (pmode) {
8159 case PROC_PARAMS_NOWARN: m_doV = true; m_doNConst = true; m_params = true;
8160 m_required = false; break;
8161 case PROC_PARAMS: m_doV = true; m_doNConst = true; m_params = true;
8162 m_required = true; break;
8163 case PROC_GENERATE: m_doV = true; m_doNConst = true; m_params = true;
8164 m_required = true; m_doGenerate = true; break;
8165 case PROC_LIVE: break;
8166 case PROC_V_WARN: m_doV = true; m_doNConst = true; m_warn = true; m_convertLogicToBit = true; break;
8167 case PROC_V_NOWARN: m_doV = true; m_doNConst = true; break;
8168 case PROC_V_EXPENSIVE: m_doV = true; m_doNConst = true; m_doExpensive = true; break;
8169 case PROC_CPP: m_doV = false; m_doNConst = true; m_doCpp = true; break;
8170 default: v3fatalSrc("Bad case"); break;
8171 }
8172 // clang-format on
8173 }
8174 ~ConstVisitor() override {
8175 if (m_doCpp) {
8176 if (m_globalPass) {
8177 V3Stats::addStat("Optimizations, Const bit op reduction", m_statBitOpReduction);
8178 } else {
8179 V3Stats::addStatSum("Optimizations, Const bit op reduction", m_statBitOpReduction);
8180 }
8181 }
8182 }
8183
8184 AstNode* mainAcceptEdit(AstNode* nodep) {
8185 VIsCached::clearCacheTree(); // Avoid using any stale isPure
8186 // Operate starting at a random place
8187 return iterateSubtreeReturnEdits(nodep);
8188 }
8189 };
8190
8191 uint32_t ConstVisitor::s_globalPassNum = 0;
8192
8193 //######################################################################
8194 // Const class functions
8195
8196 //! Force this cell node's parameter list to become a constant
8197 //! @return Pointer to the edited node.
8198 AstNode* V3Const::constifyParamsEdit(AstNode* nodep) {
8199 // if (debug() > 0) nodep->dumpTree("- forceConPRE : ");
8200 // Resize even if the node already has a width, because buried in the tree
8201 // we may have a node we just created with signing, etc, that isn't sized yet.
8202
8203 // Make sure we've sized everything first
8204 nodep = V3Width::widthParamsEdit(nodep);
8205 ConstVisitor visitor{ConstVisitor::PROC_PARAMS, /* globalPass: */ false};
8206 if (AstVar* const varp = VN_CAST(nodep, Var)) {
8207 // If a var wants to be constified, it's really a param, and
8208 // we want the value to be constant. We aren't passed just the
8209 // init value because we need widthing above to handle the var's type.
8210 if (varp->valuep()) visitor.mainAcceptEdit(varp->valuep());
8211 } else {
8212 nodep = visitor.mainAcceptEdit(nodep);
8213 }
8214 // Because we do edits, nodep links may get trashed and core dump this.
8215 // if (debug() > 0) nodep->dumpTree("- forceConDONE: ");
8216 return nodep;
8217 }
8218
8219 //! Constify this cell node's parameter list if possible
8220 //! @return Pointer to the edited node.
8221 AstNode* V3Const::constifyParamsNoWarnEdit(AstNode* nodep) {
8222 // if (debug() > 0) nodep->dumpTree("- forceConPRE : ");
8223 // Resize even if the node already has a width, because buried in the tree
8224 // we may have a node we just created with signing, etc, that isn't sized yet.
8225
8226 // Make sure we've sized everything first
8227 nodep = V3Width::widthParamsEdit(nodep);
8228 ConstVisitor visitor{ConstVisitor::PROC_PARAMS_NOWARN, /* globalPass: */ false};
8229 if (AstVar* const varp = VN_CAST(nodep, Var)) {
8230 // If a var wants to be constified, it's really a param, and
8231 // we want the value to be constant. We aren't passed just the
8232 // init value because we need widthing above to handle the var's type.
8233 if (varp->valuep()) visitor.mainAcceptEdit(varp->valuep());
8234 } else {
8235 nodep = visitor.mainAcceptEdit(nodep);
8236 }
8237 // Because we do edits, nodep links may get trashed and core dump this.
8238 // if (debug() > 0) nodep->dumpTree("- forceConDONE: ");
8239 return nodep;
8240 }
8241
8242 //! Force this cell node's parameter list to become a constant inside generate.
8243 //! If we are inside a generated "if", "case" or "for", we don't want to
8244 //! trigger warnings when we deal with the width. It is possible that these
8245 //! are spurious, existing within sub-expressions that will not actually be
8246 //! generated. Since such occurrences, must be constant, in order to be
8247 //! something a generate block can depend on, we can wait until later to do the
8248 //! width check.
8249 //! @return Pointer to the edited node.
8250 AstNode* V3Const::constifyGenerateParamsEdit(AstNode* nodep) {
8251 // if (debug() > 0) nodep->dumpTree("- forceConPRE:: ");
8252 // Resize even if the node already has a width, because buried in the tree
8253 // we may have a node we just created with signing, etc, that isn't sized
8254 // yet.
8255
8256 // Make sure we've sized everything first
8257 nodep = V3Width::widthGenerateParamsEdit(nodep);
8258 ConstVisitor visitor{ConstVisitor::PROC_GENERATE, /* globalPass: */ false};
8259 if (AstVar* const varp = VN_CAST(nodep, Var)) {
8260 // If a var wants to be constified, it's really a param, and
8261 // we want the value to be constant. We aren't passed just the
8262 // init value because we need widthing above to handle the var's type.
8263 if (varp->valuep()) visitor.mainAcceptEdit(varp->valuep());
8264 } else {
8265 nodep = visitor.mainAcceptEdit(nodep);
8266 }
8267 // Because we do edits, nodep links may get trashed and core dump this.
8268 // if (debug() > 0) nodep->dumpTree("- forceConDONE: ");
8269 return nodep;
8270 }
8271
8272 void V3Const::constifyAllLint(AstNetlist* nodep) {
8273 // Only call from Verilator.cpp, as it uses user#'s
8274 UINFO(2, __FUNCTION__ << ": " << endl);
8275 {
8276 ConstVisitor visitor{ConstVisitor::PROC_V_WARN, /* globalPass: */ true};
8277 (void)visitor.mainAcceptEdit(nodep);
8278 } // Destruct before checking
8279 V3Global::dumpCheckGlobalTree("const", 0, dumpTreeEitherLevel() >= 3);
8280 }
8281
8282 void V3Const::constifyCpp(AstNetlist* nodep) {
8283 UINFO(2, __FUNCTION__ << ": " << endl);
8284 {
8285 ConstVisitor visitor{ConstVisitor::PROC_CPP, /* globalPass: */ true};
8286 (void)visitor.mainAcceptEdit(nodep);
8287 } // Destruct before checking
8288 V3Global::dumpCheckGlobalTree("const_cpp", 0, dumpTreeEitherLevel() >= 3);
8289 }
8290
8291 AstNode* V3Const::constifyEdit(AstNode* nodep) {
8292 ConstVisitor visitor{ConstVisitor::PROC_V_NOWARN, /* globalPass: */ false};
8293 nodep = visitor.mainAcceptEdit(nodep);
8294 return nodep;
8295 }
8296
8297 AstNode* V3Const::constifyEditCpp(AstNode* nodep) {
8298 ConstVisitor visitor{ConstVisitor::PROC_CPP, /* globalPass: */ false};
8299 nodep = visitor.mainAcceptEdit(nodep);
8300 return nodep;
8301 }
8302
8303 void V3Const::constifyAllLive(AstNetlist* nodep) {
8304 // Only call from Verilator.cpp, as it uses user#'s
8305 // This only pushes constants up, doesn't make any other edits
8306 // IE doesn't prune dead statements, as we need to do some usability checks after this
8307 UINFO(2, __FUNCTION__ << ": " << endl);
8308 {
8309 ConstVisitor visitor{ConstVisitor::PROC_LIVE, /* globalPass: */ true};
8310 (void)visitor.mainAcceptEdit(nodep);
8311 } // Destruct before checking
8312 V3Global::dumpCheckGlobalTree("const", 0, dumpTreeEitherLevel() >= 3);
8313 }
8314
8315 void V3Const::constifyAll(AstNetlist* nodep) {
8316 // Only call from Verilator.cpp, as it uses user#'s
8317 UINFO(2, __FUNCTION__ << ": " << endl);
8318 {
8319 ConstVisitor visitor{ConstVisitor::PROC_V_EXPENSIVE, /* globalPass: */ true};
8320 (void)visitor.mainAcceptEdit(nodep);
8321 } // Destruct before checking
8322 V3Global::dumpCheckGlobalTree("const", 0, dumpTreeEitherLevel() >= 3);
8323 }
8324
8325 AstNode* V3Const::constifyExpensiveEdit(AstNode* nodep) {
8326 ConstVisitor visitor{ConstVisitor::PROC_V_EXPENSIVE, /* globalPass: */ false};
8327 nodep = visitor.mainAcceptEdit(nodep);
8328 return nodep;
8329 }
8330